0,0 → 1,2266 |
/* |
Copyright (C) Intel Corp. 2006. All Rights Reserved. |
Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to |
develop this 3D driver. |
|
Permission is hereby granted, free of charge, to any person obtaining |
a copy of this software and associated documentation files (the |
"Software"), to deal in the Software without restriction, including |
without limitation the rights to use, copy, modify, merge, publish, |
distribute, sublicense, and/or sell copies of the Software, and to |
permit persons to whom the Software is furnished to do so, subject to |
the following conditions: |
|
The above copyright notice and this permission notice (including the |
next paragraph) shall be included in all copies or substantial |
portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE |
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
**********************************************************************/ |
/* |
* Authors: |
* Keith Whitwell <keith@tungstengraphics.com> |
*/ |
|
|
#ifndef BRW_EU_H |
#define BRW_EU_H |
|
#include <stdbool.h> |
#include <stdint.h> |
#include <stdio.h> |
#include <assert.h> |
|
#define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6)) |
#define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3) |
|
#define BRW_SWIZZLE_NOOP BRW_SWIZZLE4(0,1,2,3) |
#define BRW_SWIZZLE_XYZW BRW_SWIZZLE4(0,1,2,3) |
#define BRW_SWIZZLE_XXXX BRW_SWIZZLE4(0,0,0,0) |
#define BRW_SWIZZLE_YYYY BRW_SWIZZLE4(1,1,1,1) |
#define BRW_SWIZZLE_ZZZZ BRW_SWIZZLE4(2,2,2,2) |
#define BRW_SWIZZLE_WWWW BRW_SWIZZLE4(3,3,3,3) |
#define BRW_SWIZZLE_XYXY BRW_SWIZZLE4(0,1,0,1) |
|
#define WRITEMASK_X 0x1 |
#define WRITEMASK_Y 0x2 |
#define WRITEMASK_Z 0x4 |
#define WRITEMASK_W 0x8 |
|
#define WRITEMASK_XY (WRITEMASK_X | WRITEMASK_Y) |
#define WRITEMASK_XYZ (WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z) |
#define WRITEMASK_XYZW (WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z | WRITEMASK_W) |
|
/** Number of general purpose registers (VS, WM, etc) */ |
#define BRW_MAX_GRF 128 |
|
/** Number of message register file registers */ |
#define BRW_MAX_MRF 16 |
|
|
#define BRW_ALIGN_1 0 |
#define BRW_ALIGN_16 1 |
|
#define BRW_ADDRESS_DIRECT 0 |
#define BRW_ADDRESS_REGISTER_INDIRECT_REGISTER 1 |
|
#define BRW_CHANNEL_X 0 |
#define BRW_CHANNEL_Y 1 |
#define BRW_CHANNEL_Z 2 |
#define BRW_CHANNEL_W 3 |
|
enum brw_compression { |
BRW_COMPRESSION_NONE, |
BRW_COMPRESSION_2NDHALF, |
BRW_COMPRESSION_COMPRESSED, |
}; |
|
#define GEN6_COMPRESSION_1Q 0 |
#define GEN6_COMPRESSION_2Q 1 |
#define GEN6_COMPRESSION_3Q 2 |
#define GEN6_COMPRESSION_4Q 3 |
#define GEN6_COMPRESSION_1H 0 |
#define GEN6_COMPRESSION_2H 2 |
|
#define BRW_CONDITIONAL_NONE 0 |
#define BRW_CONDITIONAL_Z 1 |
#define BRW_CONDITIONAL_NZ 2 |
#define BRW_CONDITIONAL_EQ 1 /* Z */ |
#define BRW_CONDITIONAL_NEQ 2 /* NZ */ |
#define BRW_CONDITIONAL_G 3 |
#define BRW_CONDITIONAL_GE 4 |
#define BRW_CONDITIONAL_L 5 |
#define BRW_CONDITIONAL_LE 6 |
#define BRW_CONDITIONAL_R 7 |
#define BRW_CONDITIONAL_O 8 |
#define BRW_CONDITIONAL_U 9 |
|
#define BRW_DEBUG_NONE 0 |
#define BRW_DEBUG_BREAKPOINT 1 |
|
#define BRW_DEPENDENCY_NORMAL 0 |
#define BRW_DEPENDENCY_NOTCLEARED 1 |
#define BRW_DEPENDENCY_NOTCHECKED 2 |
#define BRW_DEPENDENCY_DISABLE 3 |
|
#define BRW_EXECUTE_1 0 |
#define BRW_EXECUTE_2 1 |
#define BRW_EXECUTE_4 2 |
#define BRW_EXECUTE_8 3 |
#define BRW_EXECUTE_16 4 |
#define BRW_EXECUTE_32 5 |
|
#define BRW_HORIZONTAL_STRIDE_0 0 |
#define BRW_HORIZONTAL_STRIDE_1 1 |
#define BRW_HORIZONTAL_STRIDE_2 2 |
#define BRW_HORIZONTAL_STRIDE_4 3 |
|
#define BRW_INSTRUCTION_NORMAL 0 |
#define BRW_INSTRUCTION_SATURATE 1 |
|
#define BRW_MASK_ENABLE 0 |
#define BRW_MASK_DISABLE 1 |
|
/** @{ |
* |
* Gen6 has replaced "mask enable/disable" with WECtrl, which is |
* effectively the same but much simpler to think about. Now, there |
* are two contributors ANDed together to whether channels are |
* executed: The predication on the instruction, and the channel write |
* enable. |
*/ |
/** |
* This is the default value. It means that a channel's write enable is set |
* if the per-channel IP is pointing at this instruction. |
*/ |
#define BRW_WE_NORMAL 0 |
/** |
* This is used like BRW_MASK_DISABLE, and causes all channels to have |
* their write enable set. Note that predication still contributes to |
* whether the channel actually gets written. |
*/ |
#define BRW_WE_ALL 1 |
/** @} */ |
|
enum opcode { |
/* These are the actual hardware opcodes. */ |
BRW_OPCODE_MOV = 1, |
BRW_OPCODE_SEL = 2, |
BRW_OPCODE_NOT = 4, |
BRW_OPCODE_AND = 5, |
BRW_OPCODE_OR = 6, |
BRW_OPCODE_XOR = 7, |
BRW_OPCODE_SHR = 8, |
BRW_OPCODE_SHL = 9, |
BRW_OPCODE_RSR = 10, |
BRW_OPCODE_RSL = 11, |
BRW_OPCODE_ASR = 12, |
BRW_OPCODE_CMP = 16, |
BRW_OPCODE_CMPN = 17, |
BRW_OPCODE_JMPI = 32, |
BRW_OPCODE_IF = 34, |
BRW_OPCODE_IFF = 35, |
BRW_OPCODE_ELSE = 36, |
BRW_OPCODE_ENDIF = 37, |
BRW_OPCODE_DO = 38, |
BRW_OPCODE_WHILE = 39, |
BRW_OPCODE_BREAK = 40, |
BRW_OPCODE_CONTINUE = 41, |
BRW_OPCODE_HALT = 42, |
BRW_OPCODE_MSAVE = 44, |
BRW_OPCODE_MRESTORE = 45, |
BRW_OPCODE_PUSH = 46, |
BRW_OPCODE_POP = 47, |
BRW_OPCODE_WAIT = 48, |
BRW_OPCODE_SEND = 49, |
BRW_OPCODE_SENDC = 50, |
BRW_OPCODE_MATH = 56, |
BRW_OPCODE_ADD = 64, |
BRW_OPCODE_MUL = 65, |
BRW_OPCODE_AVG = 66, |
BRW_OPCODE_FRC = 67, |
BRW_OPCODE_RNDU = 68, |
BRW_OPCODE_RNDD = 69, |
BRW_OPCODE_RNDE = 70, |
BRW_OPCODE_RNDZ = 71, |
BRW_OPCODE_MAC = 72, |
BRW_OPCODE_MACH = 73, |
BRW_OPCODE_LZD = 74, |
BRW_OPCODE_SAD2 = 80, |
BRW_OPCODE_SADA2 = 81, |
BRW_OPCODE_DP4 = 84, |
BRW_OPCODE_DPH = 85, |
BRW_OPCODE_DP3 = 86, |
BRW_OPCODE_DP2 = 87, |
BRW_OPCODE_DPA2 = 88, |
BRW_OPCODE_LINE = 89, |
BRW_OPCODE_PLN = 90, |
BRW_OPCODE_NOP = 126, |
|
/* These are compiler backend opcodes that get translated into other |
* instructions. |
*/ |
FS_OPCODE_FB_WRITE = 128, |
SHADER_OPCODE_RCP, |
SHADER_OPCODE_RSQ, |
SHADER_OPCODE_SQRT, |
SHADER_OPCODE_EXP2, |
SHADER_OPCODE_LOG2, |
SHADER_OPCODE_POW, |
SHADER_OPCODE_SIN, |
SHADER_OPCODE_COS, |
FS_OPCODE_DDX, |
FS_OPCODE_DDY, |
FS_OPCODE_PIXEL_X, |
FS_OPCODE_PIXEL_Y, |
FS_OPCODE_CINTERP, |
FS_OPCODE_LINTERP, |
FS_OPCODE_TEX, |
FS_OPCODE_TXB, |
FS_OPCODE_TXD, |
FS_OPCODE_TXF, |
FS_OPCODE_TXL, |
FS_OPCODE_TXS, |
FS_OPCODE_DISCARD, |
FS_OPCODE_SPILL, |
FS_OPCODE_UNSPILL, |
FS_OPCODE_PULL_CONSTANT_LOAD, |
|
VS_OPCODE_URB_WRITE, |
VS_OPCODE_SCRATCH_READ, |
VS_OPCODE_SCRATCH_WRITE, |
VS_OPCODE_PULL_CONSTANT_LOAD, |
}; |
|
#define BRW_PREDICATE_NONE 0 |
#define BRW_PREDICATE_NORMAL 1 |
#define BRW_PREDICATE_ALIGN1_ANYV 2 |
#define BRW_PREDICATE_ALIGN1_ALLV 3 |
#define BRW_PREDICATE_ALIGN1_ANY2H 4 |
#define BRW_PREDICATE_ALIGN1_ALL2H 5 |
#define BRW_PREDICATE_ALIGN1_ANY4H 6 |
#define BRW_PREDICATE_ALIGN1_ALL4H 7 |
#define BRW_PREDICATE_ALIGN1_ANY8H 8 |
#define BRW_PREDICATE_ALIGN1_ALL8H 9 |
#define BRW_PREDICATE_ALIGN1_ANY16H 10 |
#define BRW_PREDICATE_ALIGN1_ALL16H 11 |
#define BRW_PREDICATE_ALIGN16_REPLICATE_X 2 |
#define BRW_PREDICATE_ALIGN16_REPLICATE_Y 3 |
#define BRW_PREDICATE_ALIGN16_REPLICATE_Z 4 |
#define BRW_PREDICATE_ALIGN16_REPLICATE_W 5 |
#define BRW_PREDICATE_ALIGN16_ANY4H 6 |
#define BRW_PREDICATE_ALIGN16_ALL4H 7 |
|
#define BRW_ARCHITECTURE_REGISTER_FILE 0 |
#define BRW_GENERAL_REGISTER_FILE 1 |
#define BRW_MESSAGE_REGISTER_FILE 2 |
#define BRW_IMMEDIATE_VALUE 3 |
|
#define BRW_REGISTER_TYPE_UD 0 |
#define BRW_REGISTER_TYPE_D 1 |
#define BRW_REGISTER_TYPE_UW 2 |
#define BRW_REGISTER_TYPE_W 3 |
#define BRW_REGISTER_TYPE_UB 4 |
#define BRW_REGISTER_TYPE_B 5 |
#define BRW_REGISTER_TYPE_VF 5 /* packed float vector, immediates only? */ |
#define BRW_REGISTER_TYPE_HF 6 |
#define BRW_REGISTER_TYPE_V 6 /* packed int vector, immediates only, uword dest only */ |
#define BRW_REGISTER_TYPE_F 7 |
|
#define BRW_ARF_NULL 0x00 |
#define BRW_ARF_ADDRESS 0x10 |
#define BRW_ARF_ACCUMULATOR 0x20 |
#define BRW_ARF_FLAG 0x30 |
#define BRW_ARF_MASK 0x40 |
#define BRW_ARF_MASK_STACK 0x50 |
#define BRW_ARF_MASK_STACK_DEPTH 0x60 |
#define BRW_ARF_STATE 0x70 |
#define BRW_ARF_CONTROL 0x80 |
#define BRW_ARF_NOTIFICATION_COUNT 0x90 |
#define BRW_ARF_IP 0xA0 |
|
#define BRW_MRF_COMPR4 (1 << 7) |
|
#define BRW_AMASK 0 |
#define BRW_IMASK 1 |
#define BRW_LMASK 2 |
#define BRW_CMASK 3 |
|
#define BRW_THREAD_NORMAL 0 |
#define BRW_THREAD_ATOMIC 1 |
#define BRW_THREAD_SWITCH 2 |
|
#define BRW_VERTICAL_STRIDE_0 0 |
#define BRW_VERTICAL_STRIDE_1 1 |
#define BRW_VERTICAL_STRIDE_2 2 |
#define BRW_VERTICAL_STRIDE_4 3 |
#define BRW_VERTICAL_STRIDE_8 4 |
#define BRW_VERTICAL_STRIDE_16 5 |
#define BRW_VERTICAL_STRIDE_32 6 |
#define BRW_VERTICAL_STRIDE_64 7 |
#define BRW_VERTICAL_STRIDE_128 8 |
#define BRW_VERTICAL_STRIDE_256 9 |
#define BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL 0xF |
|
#define BRW_WIDTH_1 0 |
#define BRW_WIDTH_2 1 |
#define BRW_WIDTH_4 2 |
#define BRW_WIDTH_8 3 |
#define BRW_WIDTH_16 4 |
|
#define BRW_STATELESS_BUFFER_BOUNDARY_1K 0 |
#define BRW_STATELESS_BUFFER_BOUNDARY_2K 1 |
#define BRW_STATELESS_BUFFER_BOUNDARY_4K 2 |
#define BRW_STATELESS_BUFFER_BOUNDARY_8K 3 |
#define BRW_STATELESS_BUFFER_BOUNDARY_16K 4 |
#define BRW_STATELESS_BUFFER_BOUNDARY_32K 5 |
#define BRW_STATELESS_BUFFER_BOUNDARY_64K 6 |
#define BRW_STATELESS_BUFFER_BOUNDARY_128K 7 |
#define BRW_STATELESS_BUFFER_BOUNDARY_256K 8 |
#define BRW_STATELESS_BUFFER_BOUNDARY_512K 9 |
#define BRW_STATELESS_BUFFER_BOUNDARY_1M 10 |
#define BRW_STATELESS_BUFFER_BOUNDARY_2M 11 |
|
#define BRW_POLYGON_FACING_FRONT 0 |
#define BRW_POLYGON_FACING_BACK 1 |
|
#define BRW_MESSAGE_TARGET_NULL 0 |
#define BRW_MESSAGE_TARGET_MATH 1 /* reserved on GEN6 */ |
#define BRW_MESSAGE_TARGET_SAMPLER 2 |
#define BRW_MESSAGE_TARGET_GATEWAY 3 |
#define BRW_MESSAGE_TARGET_DATAPORT_READ 4 |
#define BRW_MESSAGE_TARGET_DATAPORT_WRITE 5 |
#define BRW_MESSAGE_TARGET_URB 6 |
#define BRW_MESSAGE_TARGET_THREAD_SPAWNER 7 |
|
#define GEN6_MESSAGE_TARGET_DP_SAMPLER_CACHE 4 |
#define GEN6_MESSAGE_TARGET_DP_RENDER_CACHE 5 |
#define GEN6_MESSAGE_TARGET_DP_CONST_CACHE 9 |
|
#define BRW_SAMPLER_RETURN_FORMAT_FLOAT32 0 |
#define BRW_SAMPLER_RETURN_FORMAT_UINT32 2 |
#define BRW_SAMPLER_RETURN_FORMAT_SINT32 3 |
|
#define BRW_SAMPLER_MESSAGE_SAMPLE 0 |
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE 0 |
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE 0 |
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS 0 |
#define BRW_SAMPLER_MESSAGE_SIMD8_KILLPIX 1 |
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD 1 |
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD 1 |
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_GRADIENTS 2 |
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_GRADIENTS 2 |
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE 0 |
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE 2 |
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_COMPARE 0 |
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_COMPARE 1 |
#define BRW_SAMPLER_MESSAGE_SIMD4X2_RESINFO 2 |
#define BRW_SAMPLER_MESSAGE_SIMD16_RESINFO 2 |
#define BRW_SAMPLER_MESSAGE_SIMD4X2_LD 3 |
#define BRW_SAMPLER_MESSAGE_SIMD8_LD 3 |
#define BRW_SAMPLER_MESSAGE_SIMD16_LD 3 |
|
#define GEN5_SAMPLER_MESSAGE_SAMPLE 0 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS 1 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_LOD 2 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_COMPARE 3 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_DERIVS 4 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_BIAS_COMPARE 5 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_LOD_COMPARE 6 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_LD 7 |
#define GEN5_SAMPLER_MESSAGE_SAMPLE_RESINFO 10 |
|
/* for GEN5 only */ |
#define BRW_SAMPLER_SIMD_MODE_SIMD4X2 0 |
#define BRW_SAMPLER_SIMD_MODE_SIMD8 1 |
#define BRW_SAMPLER_SIMD_MODE_SIMD16 2 |
#define BRW_SAMPLER_SIMD_MODE_SIMD32_64 3 |
|
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0 |
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1 |
#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2 |
#define BRW_DATAPORT_OWORD_BLOCK_4_OWORDS 3 |
#define BRW_DATAPORT_OWORD_BLOCK_8_OWORDS 4 |
|
#define BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD 0 |
#define BRW_DATAPORT_OWORD_DUAL_BLOCK_4OWORDS 2 |
|
#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS 2 |
#define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS 3 |
|
/* This one stays the same across generations. */ |
#define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ 0 |
/* GEN4 */ |
#define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 1 |
#define BRW_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ 2 |
#define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 3 |
/* G45, GEN5 */ |
#define G45_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ 1 |
#define G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 2 |
#define G45_DATAPORT_READ_MESSAGE_AVC_LOOP_FILTER_READ 3 |
#define G45_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ 4 |
#define G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 6 |
/* GEN6 */ |
#define GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ 1 |
#define GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ 2 |
#define GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ 4 |
#define GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ 5 |
#define GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ 6 |
|
#define BRW_DATAPORT_READ_TARGET_DATA_CACHE 0 |
#define BRW_DATAPORT_READ_TARGET_RENDER_CACHE 1 |
#define BRW_DATAPORT_READ_TARGET_SAMPLER_CACHE 2 |
|
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE 0 |
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE_REPLICATED 1 |
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN01 2 |
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_DUAL_SOURCE_SUBSPAN23 3 |
#define BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD8_SINGLE_SOURCE_SUBSPAN01 4 |
|
/** |
* Message target: Shared Function ID for where to SEND a message. |
* |
* These are enumerated in the ISA reference under "send - Send Message". |
* In particular, see the following tables: |
* - G45 PRM, Volume 4, Table 14-15 "Message Descriptor Definition" |
* - Sandybridge PRM, Volume 4 Part 2, Table 8-16 "Extended Message Descriptor" |
* - BSpec, Volume 1a (GPU Overview) / Graphics Processing Engine (GPE) / |
* Overview / GPE Function IDs |
*/ |
enum brw_message_target { |
BRW_SFID_NULL = 0, |
BRW_SFID_MATH = 1, /* Only valid on Gen4-5 */ |
BRW_SFID_SAMPLER = 2, |
BRW_SFID_MESSAGE_GATEWAY = 3, |
BRW_SFID_DATAPORT_READ = 4, |
BRW_SFID_DATAPORT_WRITE = 5, |
BRW_SFID_URB = 6, |
BRW_SFID_THREAD_SPAWNER = 7, |
|
GEN6_SFID_DATAPORT_SAMPLER_CACHE = 4, |
GEN6_SFID_DATAPORT_RENDER_CACHE = 5, |
GEN6_SFID_DATAPORT_CONSTANT_CACHE = 9, |
|
GEN7_SFID_DATAPORT_DATA_CACHE = 10, |
}; |
|
#define GEN7_MESSAGE_TARGET_DP_DATA_CACHE 10 |
|
#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 0 |
#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 1 |
#define BRW_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE 2 |
#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 3 |
#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 4 |
#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE 5 |
#define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE 7 |
|
/* GEN6 */ |
#define GEN6_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE 7 |
#define GEN6_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE 8 |
#define GEN6_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE 9 |
#define GEN6_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE 10 |
#define GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE 11 |
#define GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE 12 |
#define GEN6_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE 13 |
#define GEN6_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE 14 |
|
#define BRW_MATH_FUNCTION_INV 1 |
#define BRW_MATH_FUNCTION_LOG 2 |
#define BRW_MATH_FUNCTION_EXP 3 |
#define BRW_MATH_FUNCTION_SQRT 4 |
#define BRW_MATH_FUNCTION_RSQ 5 |
#define BRW_MATH_FUNCTION_SIN 6 /* was 7 */ |
#define BRW_MATH_FUNCTION_COS 7 /* was 8 */ |
#define BRW_MATH_FUNCTION_SINCOS 8 /* was 6 */ |
#define BRW_MATH_FUNCTION_TAN 9 /* gen4 */ |
#define BRW_MATH_FUNCTION_FDIV 9 /* gen6+ */ |
#define BRW_MATH_FUNCTION_POW 10 |
#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER 11 |
#define BRW_MATH_FUNCTION_INT_DIV_QUOTIENT 12 |
#define BRW_MATH_FUNCTION_INT_DIV_REMAINDER 13 |
|
#define BRW_MATH_INTEGER_UNSIGNED 0 |
#define BRW_MATH_INTEGER_SIGNED 1 |
|
#define BRW_MATH_PRECISION_FULL 0 |
#define BRW_MATH_PRECISION_PARTIAL 1 |
|
#define BRW_MATH_SATURATE_NONE 0 |
#define BRW_MATH_SATURATE_SATURATE 1 |
|
#define BRW_MATH_DATA_VECTOR 0 |
#define BRW_MATH_DATA_SCALAR 1 |
|
#define BRW_URB_OPCODE_WRITE 0 |
|
#define BRW_URB_SWIZZLE_NONE 0 |
#define BRW_URB_SWIZZLE_INTERLEAVE 1 |
#define BRW_URB_SWIZZLE_TRANSPOSE 2 |
|
#define BRW_SCRATCH_SPACE_SIZE_1K 0 |
#define BRW_SCRATCH_SPACE_SIZE_2K 1 |
#define BRW_SCRATCH_SPACE_SIZE_4K 2 |
#define BRW_SCRATCH_SPACE_SIZE_8K 3 |
#define BRW_SCRATCH_SPACE_SIZE_16K 4 |
#define BRW_SCRATCH_SPACE_SIZE_32K 5 |
#define BRW_SCRATCH_SPACE_SIZE_64K 6 |
#define BRW_SCRATCH_SPACE_SIZE_128K 7 |
#define BRW_SCRATCH_SPACE_SIZE_256K 8 |
#define BRW_SCRATCH_SPACE_SIZE_512K 9 |
#define BRW_SCRATCH_SPACE_SIZE_1M 10 |
#define BRW_SCRATCH_SPACE_SIZE_2M 11 |
|
#define REG_SIZE (8*4) |
|
struct brw_instruction { |
struct { |
unsigned opcode:7; |
unsigned pad:1; |
unsigned access_mode:1; |
unsigned mask_control:1; |
unsigned dependency_control:2; |
unsigned compression_control:2; /* gen6: quater control */ |
unsigned thread_control:2; |
unsigned predicate_control:4; |
unsigned predicate_inverse:1; |
unsigned execution_size:3; |
/** |
* Conditional Modifier for most instructions. On Gen6+, this is also |
* used for the SEND instruction's Message Target/SFID. |
*/ |
unsigned destreg__conditionalmod:4; |
unsigned acc_wr_control:1; |
unsigned cmpt_control:1; |
unsigned debug_control:1; |
unsigned saturate:1; |
} header; |
|
union { |
struct { |
unsigned dest_reg_file:2; |
unsigned dest_reg_type:3; |
unsigned src0_reg_file:2; |
unsigned src0_reg_type:3; |
unsigned src1_reg_file:2; |
unsigned src1_reg_type:3; |
unsigned pad:1; |
unsigned dest_subreg_nr:5; |
unsigned dest_reg_nr:8; |
unsigned dest_horiz_stride:2; |
unsigned dest_address_mode:1; |
} da1; |
|
struct { |
unsigned dest_reg_file:2; |
unsigned dest_reg_type:3; |
unsigned src0_reg_file:2; |
unsigned src0_reg_type:3; |
unsigned src1_reg_file:2; /* 0x00000c00 */ |
unsigned src1_reg_type:3; /* 0x00007000 */ |
unsigned pad:1; |
int dest_indirect_offset:10; /* offset against the deref'd address reg */ |
unsigned dest_subreg_nr:3; /* subnr for the address reg a0.x */ |
unsigned dest_horiz_stride:2; |
unsigned dest_address_mode:1; |
} ia1; |
|
struct { |
unsigned dest_reg_file:2; |
unsigned dest_reg_type:3; |
unsigned src0_reg_file:2; |
unsigned src0_reg_type:3; |
unsigned src1_reg_file:2; |
unsigned src1_reg_type:3; |
unsigned pad:1; |
unsigned dest_writemask:4; |
unsigned dest_subreg_nr:1; |
unsigned dest_reg_nr:8; |
unsigned dest_horiz_stride:2; |
unsigned dest_address_mode:1; |
} da16; |
|
struct { |
unsigned dest_reg_file:2; |
unsigned dest_reg_type:3; |
unsigned src0_reg_file:2; |
unsigned src0_reg_type:3; |
unsigned pad0:6; |
unsigned dest_writemask:4; |
int dest_indirect_offset:6; |
unsigned dest_subreg_nr:3; |
unsigned dest_horiz_stride:2; |
unsigned dest_address_mode:1; |
} ia16; |
|
struct { |
unsigned dest_reg_file:2; |
unsigned dest_reg_type:3; |
unsigned src0_reg_file:2; |
unsigned src0_reg_type:3; |
unsigned src1_reg_file:2; |
unsigned src1_reg_type:3; |
unsigned pad:1; |
|
int jump_count:16; |
} branch_gen6; |
|
struct { |
unsigned dest_reg_file:1; |
unsigned flag_subreg_num:1; |
unsigned pad0:2; |
unsigned src0_abs:1; |
unsigned src0_negate:1; |
unsigned src1_abs:1; |
unsigned src1_negate:1; |
unsigned src2_abs:1; |
unsigned src2_negate:1; |
unsigned pad1:7; |
unsigned dest_writemask:4; |
unsigned dest_subreg_nr:3; |
unsigned dest_reg_nr:8; |
} da3src; |
} bits1; |
|
|
union { |
struct { |
unsigned src0_subreg_nr:5; |
unsigned src0_reg_nr:8; |
unsigned src0_abs:1; |
unsigned src0_negate:1; |
unsigned src0_address_mode:1; |
unsigned src0_horiz_stride:2; |
unsigned src0_width:3; |
unsigned src0_vert_stride:4; |
unsigned flag_subreg_nr:1; |
unsigned flag_reg_nr:1; |
unsigned pad:5; |
} da1; |
|
struct { |
int src0_indirect_offset:10; |
unsigned src0_subreg_nr:3; |
unsigned src0_abs:1; |
unsigned src0_negate:1; |
unsigned src0_address_mode:1; |
unsigned src0_horiz_stride:2; |
unsigned src0_width:3; |
unsigned src0_vert_stride:4; |
unsigned flag_subreg_nr:1; |
unsigned flag_reg_nr:1; |
unsigned pad:5; |
} ia1; |
|
struct { |
unsigned src0_swz_x:2; |
unsigned src0_swz_y:2; |
unsigned src0_subreg_nr:1; |
unsigned src0_reg_nr:8; |
unsigned src0_abs:1; |
unsigned src0_negate:1; |
unsigned src0_address_mode:1; |
unsigned src0_swz_z:2; |
unsigned src0_swz_w:2; |
unsigned pad0:1; |
unsigned src0_vert_stride:4; |
unsigned flag_subreg_nr:1; |
unsigned flag_reg_nr:1; |
unsigned pad1:5; |
} da16; |
|
struct { |
unsigned src0_swz_x:2; |
unsigned src0_swz_y:2; |
int src0_indirect_offset:6; |
unsigned src0_subreg_nr:3; |
unsigned src0_abs:1; |
unsigned src0_negate:1; |
unsigned src0_address_mode:1; |
unsigned src0_swz_z:2; |
unsigned src0_swz_w:2; |
unsigned pad0:1; |
unsigned src0_vert_stride:4; |
unsigned flag_subreg_nr:1; |
unsigned flag_reg_nr:1; |
unsigned pad1:5; |
} ia16; |
|
/* Extended Message Descriptor for Ironlake (Gen5) SEND instruction. |
* |
* Does not apply to Gen6+. The SFID/message target moved to bits |
* 27:24 of the header (destreg__conditionalmod); EOT is in bits3. |
*/ |
struct { |
unsigned pad:26; |
unsigned end_of_thread:1; |
unsigned pad1:1; |
unsigned sfid:4; |
} send_gen5; /* for Ironlake only */ |
|
struct { |
unsigned src0_rep_ctrl:1; |
unsigned src0_swizzle:8; |
unsigned src0_subreg_nr:3; |
unsigned src0_reg_nr:8; |
unsigned pad0:1; |
unsigned src1_rep_ctrl:1; |
unsigned src1_swizzle:8; |
unsigned src1_subreg_nr_low:2; |
} da3src; |
} bits2; |
|
union { |
struct { |
unsigned src1_subreg_nr:5; |
unsigned src1_reg_nr:8; |
unsigned src1_abs:1; |
unsigned src1_negate:1; |
unsigned src1_address_mode:1; |
unsigned src1_horiz_stride:2; |
unsigned src1_width:3; |
unsigned src1_vert_stride:4; |
unsigned pad0:7; |
} da1; |
|
struct { |
unsigned src1_swz_x:2; |
unsigned src1_swz_y:2; |
unsigned src1_subreg_nr:1; |
unsigned src1_reg_nr:8; |
unsigned src1_abs:1; |
unsigned src1_negate:1; |
unsigned src1_address_mode:1; |
unsigned src1_swz_z:2; |
unsigned src1_swz_w:2; |
unsigned pad1:1; |
unsigned src1_vert_stride:4; |
unsigned pad2:7; |
} da16; |
|
struct { |
int src1_indirect_offset:10; |
unsigned src1_subreg_nr:3; |
unsigned src1_abs:1; |
unsigned src1_negate:1; |
unsigned src1_address_mode:1; |
unsigned src1_horiz_stride:2; |
unsigned src1_width:3; |
unsigned src1_vert_stride:4; |
unsigned flag_subreg_nr:1; |
unsigned flag_reg_nr:1; |
unsigned pad1:5; |
} ia1; |
|
struct { |
unsigned src1_swz_x:2; |
unsigned src1_swz_y:2; |
int src1_indirect_offset:6; |
unsigned src1_subreg_nr:3; |
unsigned src1_abs:1; |
unsigned src1_negate:1; |
unsigned pad0:1; |
unsigned src1_swz_z:2; |
unsigned src1_swz_w:2; |
unsigned pad1:1; |
unsigned src1_vert_stride:4; |
unsigned flag_subreg_nr:1; |
unsigned flag_reg_nr:1; |
unsigned pad2:5; |
} ia16; |
|
struct { |
int jump_count:16; /* note: signed */ |
unsigned pop_count:4; |
unsigned pad0:12; |
} if_else; |
|
/* This is also used for gen7 IF/ELSE instructions */ |
struct { |
/* Signed jump distance to the ip to jump to if all channels |
* are disabled after the break or continue. It should point |
* to the end of the innermost control flow block, as that's |
* where some channel could get re-enabled. |
*/ |
int jip:16; |
|
/* Signed jump distance to the location to resume execution |
* of this channel if it's enabled for the break or continue. |
*/ |
int uip:16; |
} break_cont; |
|
/** |
* \defgroup SEND instructions / Message Descriptors |
* |
* @{ |
*/ |
|
/** |
* Generic Message Descriptor for Gen4 SEND instructions. The structs |
* below expand function_control to something specific for their |
* message. Due to struct packing issues, they duplicate these bits. |
* |
* See the G45 PRM, Volume 4, Table 14-15. |
*/ |
struct { |
unsigned function_control:16; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} generic; |
|
/** |
* Generic Message Descriptor for Gen5-7 SEND instructions. |
* |
* See the Sandybridge PRM, Volume 2 Part 2, Table 8-15. (Sadly, most |
* of the information on the SEND instruction is missing from the public |
* Ironlake PRM.) |
* |
* The table claims that bit 31 is reserved/MBZ on Gen6+, but it lies. |
* According to the SEND instruction description: |
* "The MSb of the message description, the EOT field, always comes from |
* bit 127 of the instruction word"...which is bit 31 of this field. |
*/ |
struct { |
unsigned function_control:19; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} generic_gen5; |
|
/** G45 PRM, Volume 4, Section 6.1.1.1 */ |
struct { |
unsigned function:4; |
unsigned int_type:1; |
unsigned precision:1; |
unsigned saturate:1; |
unsigned data_type:1; |
unsigned pad0:8; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} math; |
|
/** Ironlake PRM, Volume 4 Part 1, Section 6.1.1.1 */ |
struct { |
unsigned function:4; |
unsigned int_type:1; |
unsigned precision:1; |
unsigned saturate:1; |
unsigned data_type:1; |
unsigned snapshot:1; |
unsigned pad0:10; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} math_gen5; |
|
/** G45 PRM, Volume 4, Section 4.8.1.1.1 [DevBW] and [DevCL] */ |
struct { |
unsigned binding_table_index:8; |
unsigned sampler:4; |
unsigned return_format:2; |
unsigned msg_type:2; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} sampler; |
|
/** G45 PRM, Volume 4, Section 4.8.1.1.2 [DevCTG] */ |
struct { |
unsigned binding_table_index:8; |
unsigned sampler:4; |
unsigned msg_type:4; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} sampler_g4x; |
|
/** Ironlake PRM, Volume 4 Part 1, Section 4.11.1.1.3 */ |
struct { |
unsigned binding_table_index:8; |
unsigned sampler:4; |
unsigned msg_type:4; |
unsigned simd_mode:2; |
unsigned pad0:1; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} sampler_gen5; |
|
struct { |
unsigned binding_table_index:8; |
unsigned sampler:4; |
unsigned msg_type:5; |
unsigned simd_mode:2; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} sampler_gen7; |
|
struct brw_urb_immediate { |
unsigned opcode:4; |
unsigned offset:6; |
unsigned swizzle_control:2; |
unsigned pad:1; |
unsigned allocate:1; |
unsigned used:1; |
unsigned complete:1; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} urb; |
|
struct { |
unsigned opcode:4; |
unsigned offset:6; |
unsigned swizzle_control:2; |
unsigned pad:1; |
unsigned allocate:1; |
unsigned used:1; |
unsigned complete:1; |
unsigned pad0:3; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} urb_gen5; |
|
struct { |
unsigned opcode:3; |
unsigned offset:11; |
unsigned swizzle_control:1; |
unsigned complete:1; |
unsigned per_slot_offset:1; |
unsigned pad0:2; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} urb_gen7; |
|
/** 965 PRM, Volume 4, Section 5.10.1.1: Message Descriptor */ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:4; |
unsigned msg_type:2; |
unsigned target_cache:2; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} dp_read; |
|
/** G45 PRM, Volume 4, Section 5.10.1.1.2 */ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:3; |
unsigned msg_type:3; |
unsigned target_cache:2; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} dp_read_g4x; |
|
/** Ironlake PRM, Volume 4 Part 1, Section 5.10.2.1.2. */ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:3; |
unsigned msg_type:3; |
unsigned target_cache:2; |
unsigned pad0:3; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} dp_read_gen5; |
|
/** G45 PRM, Volume 4, Section 5.10.1.1.2. For both Gen4 and G45. */ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:3; |
unsigned last_render_target:1; |
unsigned msg_type:3; |
unsigned send_commit_msg:1; |
unsigned response_length:4; |
unsigned msg_length:4; |
unsigned msg_target:4; |
unsigned pad1:3; |
unsigned end_of_thread:1; |
} dp_write; |
|
/** Ironlake PRM, Volume 4 Part 1, Section 5.10.2.1.2. */ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:3; |
unsigned last_render_target:1; |
unsigned msg_type:3; |
unsigned send_commit_msg:1; |
unsigned pad0:3; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} dp_write_gen5; |
|
/** |
* Message for the Sandybridge Sampler Cache or Constant Cache Data Port. |
* |
* See the Sandybridge PRM, Volume 4 Part 1, Section 3.9.2.1.1. |
**/ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:5; |
unsigned msg_type:3; |
unsigned pad0:3; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} gen6_dp_sampler_const_cache; |
|
/** |
* Message for the Sandybridge Render Cache Data Port. |
* |
* Most fields are defined in the Sandybridge PRM, Volume 4 Part 1, |
* Section 3.9.2.1.1: Message Descriptor. |
* |
* "Slot Group Select" and "Last Render Target" are part of the |
* 5-bit message control for Render Target Write messages. See |
* Section 3.9.9.2.1 of the same volume. |
*/ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:3; |
unsigned slot_group_select:1; |
unsigned last_render_target:1; |
unsigned msg_type:4; |
unsigned send_commit_msg:1; |
unsigned pad0:1; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad1:2; |
unsigned end_of_thread:1; |
} gen6_dp; |
|
/** |
* Message for any of the Gen7 Data Port caches. |
* |
* Most fields are defined in BSpec volume 5c.2 Data Port / Messages / |
* Data Port Messages / Message Descriptor. Once again, "Slot Group |
* Select" and "Last Render Target" are part of the 6-bit message |
* control for Render Target Writes. |
*/ |
struct { |
unsigned binding_table_index:8; |
unsigned msg_control:3; |
unsigned slot_group_select:1; |
unsigned last_render_target:1; |
unsigned msg_control_pad:1; |
unsigned msg_type:4; |
unsigned pad1:1; |
unsigned header_present:1; |
unsigned response_length:5; |
unsigned msg_length:4; |
unsigned pad2:2; |
unsigned end_of_thread:1; |
} gen7_dp; |
/** @} */ |
|
struct { |
unsigned src1_subreg_nr_high:1; |
unsigned src1_reg_nr:8; |
unsigned pad0:1; |
unsigned src2_rep_ctrl:1; |
unsigned src2_swizzle:8; |
unsigned src2_subreg_nr:3; |
unsigned src2_reg_nr:8; |
unsigned pad1:2; |
} da3src; |
|
int d; |
unsigned ud; |
float f; |
} bits3; |
}; |
|
|
/* These aren't hardware structs, just something useful for us to pass around: |
* |
* Align1 operation has a lot of control over input ranges. Used in |
* WM programs to implement shaders decomposed into "channel serial" |
* or "structure of array" form: |
*/ |
struct brw_reg { |
unsigned type:4; |
unsigned file:2; |
unsigned nr:8; |
unsigned subnr:5; /* :1 in align16 */ |
unsigned negate:1; /* source only */ |
unsigned abs:1; /* source only */ |
unsigned vstride:4; /* source only */ |
unsigned width:3; /* src only, align1 only */ |
unsigned hstride:2; /* align1 only */ |
unsigned address_mode:1; /* relative addressing, hopefully! */ |
unsigned pad0:1; |
|
union { |
struct { |
unsigned swizzle:8; /* src only, align16 only */ |
unsigned writemask:4; /* dest only, align16 only */ |
int indirect_offset:10; /* relative addressing offset */ |
unsigned pad1:10; /* two dwords total */ |
} bits; |
|
float f; |
int d; |
unsigned ud; |
} dw1; |
}; |
|
struct brw_indirect { |
unsigned addr_subnr:4; |
int addr_offset:10; |
unsigned pad:18; |
}; |
|
#define BRW_EU_MAX_INSN_STACK 5 |
#define BRW_EU_MAX_INSN 10000 |
|
struct brw_compile { |
struct brw_instruction *store; |
unsigned nr_insn; |
|
int gen; |
|
/* Allow clients to push/pop instruction state: |
*/ |
struct brw_instruction stack[BRW_EU_MAX_INSN_STACK]; |
bool compressed_stack[BRW_EU_MAX_INSN_STACK]; |
struct brw_instruction *current; |
|
unsigned flag_value; |
bool single_program_flow; |
bool compressed; |
|
/* Control flow stacks: |
* - if_stack contains IF and ELSE instructions which must be patched |
* (and popped) once the matching ENDIF instruction is encountered. |
*/ |
struct brw_instruction **if_stack; |
int if_stack_depth; |
int if_stack_array_size; |
}; |
|
static inline int type_sz(unsigned type) |
{ |
switch (type) { |
case BRW_REGISTER_TYPE_UD: |
case BRW_REGISTER_TYPE_D: |
case BRW_REGISTER_TYPE_F: |
return 4; |
case BRW_REGISTER_TYPE_HF: |
case BRW_REGISTER_TYPE_UW: |
case BRW_REGISTER_TYPE_W: |
return 2; |
case BRW_REGISTER_TYPE_UB: |
case BRW_REGISTER_TYPE_B: |
return 1; |
default: |
return 0; |
} |
} |
|
/** |
* Construct a brw_reg. |
* \param file one of the BRW_x_REGISTER_FILE values |
* \param nr register number/index |
* \param subnr register sub number |
* \param type one of BRW_REGISTER_TYPE_x |
* \param vstride one of BRW_VERTICAL_STRIDE_x |
* \param width one of BRW_WIDTH_x |
* \param hstride one of BRW_HORIZONTAL_STRIDE_x |
* \param swizzle one of BRW_SWIZZLE_x |
* \param writemask WRITEMASK_X/Y/Z/W bitfield |
*/ |
static inline struct brw_reg brw_reg(unsigned file, |
unsigned nr, |
unsigned subnr, |
unsigned type, |
unsigned vstride, |
unsigned width, |
unsigned hstride, |
unsigned swizzle, |
unsigned writemask) |
{ |
struct brw_reg reg; |
if (file == BRW_GENERAL_REGISTER_FILE) |
assert(nr < BRW_MAX_GRF); |
else if (file == BRW_MESSAGE_REGISTER_FILE) |
assert((nr & ~(1 << 7)) < BRW_MAX_MRF); |
else if (file == BRW_ARCHITECTURE_REGISTER_FILE) |
assert(nr <= BRW_ARF_IP); |
|
reg.type = type; |
reg.file = file; |
reg.nr = nr; |
reg.subnr = subnr * type_sz(type); |
reg.negate = 0; |
reg.abs = 0; |
reg.vstride = vstride; |
reg.width = width; |
reg.hstride = hstride; |
reg.address_mode = BRW_ADDRESS_DIRECT; |
reg.pad0 = 0; |
|
/* Could do better: If the reg is r5.3<0;1,0>, we probably want to |
* set swizzle and writemask to W, as the lower bits of subnr will |
* be lost when converted to align16. This is probably too much to |
* keep track of as you'd want it adjusted by suboffset(), etc. |
* Perhaps fix up when converting to align16? |
*/ |
reg.dw1.bits.swizzle = swizzle; |
reg.dw1.bits.writemask = writemask; |
reg.dw1.bits.indirect_offset = 0; |
reg.dw1.bits.pad1 = 0; |
return reg; |
} |
|
/** Construct float[16] register */ |
static inline struct brw_reg brw_vec16_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return brw_reg(file, |
nr, |
subnr, |
BRW_REGISTER_TYPE_F, |
BRW_VERTICAL_STRIDE_16, |
BRW_WIDTH_16, |
BRW_HORIZONTAL_STRIDE_1, |
BRW_SWIZZLE_XYZW, |
WRITEMASK_XYZW); |
} |
|
/** Construct float[8] register */ |
static inline struct brw_reg brw_vec8_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return brw_reg(file, |
nr, |
subnr, |
BRW_REGISTER_TYPE_F, |
BRW_VERTICAL_STRIDE_8, |
BRW_WIDTH_8, |
BRW_HORIZONTAL_STRIDE_1, |
BRW_SWIZZLE_XYZW, |
WRITEMASK_XYZW); |
} |
|
/** Construct float[4] register */ |
static inline struct brw_reg brw_vec4_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return brw_reg(file, |
nr, |
subnr, |
BRW_REGISTER_TYPE_F, |
BRW_VERTICAL_STRIDE_4, |
BRW_WIDTH_4, |
BRW_HORIZONTAL_STRIDE_1, |
BRW_SWIZZLE_XYZW, |
WRITEMASK_XYZW); |
} |
|
/** Construct float[2] register */ |
static inline struct brw_reg brw_vec2_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return brw_reg(file, |
nr, |
subnr, |
BRW_REGISTER_TYPE_F, |
BRW_VERTICAL_STRIDE_2, |
BRW_WIDTH_2, |
BRW_HORIZONTAL_STRIDE_1, |
BRW_SWIZZLE_XYXY, |
WRITEMASK_XY); |
} |
|
/** Construct float[1] register */ |
static inline struct brw_reg brw_vec1_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return brw_reg(file, |
nr, |
subnr, |
BRW_REGISTER_TYPE_F, |
BRW_VERTICAL_STRIDE_0, |
BRW_WIDTH_1, |
BRW_HORIZONTAL_STRIDE_0, |
BRW_SWIZZLE_XXXX, |
WRITEMASK_X); |
} |
|
|
static inline struct brw_reg __retype(struct brw_reg reg, |
unsigned type) |
{ |
reg.type = type; |
return reg; |
} |
|
static inline struct brw_reg __retype_d(struct brw_reg reg) |
{ |
return __retype(reg, BRW_REGISTER_TYPE_D); |
} |
|
static inline struct brw_reg __retype_ud(struct brw_reg reg) |
{ |
return __retype(reg, BRW_REGISTER_TYPE_UD); |
} |
|
static inline struct brw_reg __retype_uw(struct brw_reg reg) |
{ |
return __retype(reg, BRW_REGISTER_TYPE_UW); |
} |
|
static inline struct brw_reg __sechalf(struct brw_reg reg) |
{ |
if (reg.vstride) |
reg.nr++; |
return reg; |
} |
|
static inline struct brw_reg __suboffset(struct brw_reg reg, |
unsigned delta) |
{ |
reg.subnr += delta * type_sz(reg.type); |
return reg; |
} |
|
static inline struct brw_reg __offset(struct brw_reg reg, |
unsigned delta) |
{ |
reg.nr += delta; |
return reg; |
} |
|
static inline struct brw_reg byte_offset(struct brw_reg reg, |
unsigned bytes) |
{ |
unsigned newoffset = reg.nr * REG_SIZE + reg.subnr + bytes; |
reg.nr = newoffset / REG_SIZE; |
reg.subnr = newoffset % REG_SIZE; |
return reg; |
} |
|
|
/** Construct unsigned word[16] register */ |
static inline struct brw_reg brw_uw16_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return __suboffset(__retype(brw_vec16_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); |
} |
|
/** Construct unsigned word[8] register */ |
static inline struct brw_reg brw_uw8_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return __suboffset(__retype(brw_vec8_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); |
} |
|
/** Construct unsigned word[1] register */ |
static inline struct brw_reg brw_uw1_reg(unsigned file, |
unsigned nr, |
unsigned subnr) |
{ |
return __suboffset(__retype(brw_vec1_reg(file, nr, 0), BRW_REGISTER_TYPE_UW), subnr); |
} |
|
static inline struct brw_reg brw_imm_reg(unsigned type) |
{ |
return brw_reg( BRW_IMMEDIATE_VALUE, |
0, |
0, |
type, |
BRW_VERTICAL_STRIDE_0, |
BRW_WIDTH_1, |
BRW_HORIZONTAL_STRIDE_0, |
0, |
0); |
} |
|
/** Construct float immediate register */ |
static inline struct brw_reg brw_imm_f(float f) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_F); |
imm.dw1.f = f; |
return imm; |
} |
|
/** Construct integer immediate register */ |
static inline struct brw_reg brw_imm_d(int d) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_D); |
imm.dw1.d = d; |
return imm; |
} |
|
/** Construct uint immediate register */ |
static inline struct brw_reg brw_imm_ud(unsigned ud) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UD); |
imm.dw1.ud = ud; |
return imm; |
} |
|
/** Construct ushort immediate register */ |
static inline struct brw_reg brw_imm_uw(uint16_t uw) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_UW); |
imm.dw1.ud = uw | (uw << 16); |
return imm; |
} |
|
/** Construct short immediate register */ |
static inline struct brw_reg brw_imm_w(int16_t w) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_W); |
imm.dw1.d = w | (w << 16); |
return imm; |
} |
|
/* brw_imm_b and brw_imm_ub aren't supported by hardware - the type |
* numbers alias with _V and _VF below: |
*/ |
|
/** Construct vector of eight signed half-byte values */ |
static inline struct brw_reg brw_imm_v(unsigned v) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_V); |
imm.vstride = BRW_VERTICAL_STRIDE_0; |
imm.width = BRW_WIDTH_8; |
imm.hstride = BRW_HORIZONTAL_STRIDE_1; |
imm.dw1.ud = v; |
return imm; |
} |
|
/** Construct vector of four 8-bit float values */ |
static inline struct brw_reg brw_imm_vf(unsigned v) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); |
imm.vstride = BRW_VERTICAL_STRIDE_0; |
imm.width = BRW_WIDTH_4; |
imm.hstride = BRW_HORIZONTAL_STRIDE_1; |
imm.dw1.ud = v; |
return imm; |
} |
|
#define VF_ZERO 0x0 |
#define VF_ONE 0x30 |
#define VF_NEG (1<<7) |
|
static inline struct brw_reg brw_imm_vf4(unsigned v0, |
unsigned v1, |
unsigned v2, |
unsigned v3) |
{ |
struct brw_reg imm = brw_imm_reg(BRW_REGISTER_TYPE_VF); |
imm.vstride = BRW_VERTICAL_STRIDE_0; |
imm.width = BRW_WIDTH_4; |
imm.hstride = BRW_HORIZONTAL_STRIDE_1; |
imm.dw1.ud = ((v0 << 0) | |
(v1 << 8) | |
(v2 << 16) | |
(v3 << 24)); |
return imm; |
} |
|
static inline struct brw_reg brw_address(struct brw_reg reg) |
{ |
return brw_imm_uw(reg.nr * REG_SIZE + reg.subnr); |
} |
|
/** Construct float[1] general-purpose register */ |
static inline struct brw_reg brw_vec1_grf(unsigned nr, unsigned subnr) |
{ |
return brw_vec1_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); |
} |
|
/** Construct float[2] general-purpose register */ |
static inline struct brw_reg brw_vec2_grf(unsigned nr, unsigned subnr) |
{ |
return brw_vec2_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); |
} |
|
/** Construct float[4] general-purpose register */ |
static inline struct brw_reg brw_vec4_grf(unsigned nr, unsigned subnr) |
{ |
return brw_vec4_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); |
} |
|
/** Construct float[8] general-purpose register */ |
static inline struct brw_reg brw_vec8_grf(unsigned nr, unsigned subnr) |
{ |
return brw_vec8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); |
} |
|
static inline struct brw_reg brw_uw8_grf(unsigned nr, unsigned subnr) |
{ |
return brw_uw8_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); |
} |
|
static inline struct brw_reg brw_uw16_grf(unsigned nr, unsigned subnr) |
{ |
return brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, nr, subnr); |
} |
|
/** Construct null register (usually used for setting condition codes) */ |
static inline struct brw_reg brw_null_reg(void) |
{ |
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_NULL, |
0); |
} |
|
static inline struct brw_reg brw_address_reg(unsigned subnr) |
{ |
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_ADDRESS, |
subnr); |
} |
|
/* If/else instructions break in align16 mode if writemask & swizzle |
* aren't xyzw. This goes against the convention for other scalar |
* regs: |
*/ |
static inline struct brw_reg brw_ip_reg(void) |
{ |
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_IP, |
0, |
BRW_REGISTER_TYPE_UD, |
BRW_VERTICAL_STRIDE_4, /* ? */ |
BRW_WIDTH_1, |
BRW_HORIZONTAL_STRIDE_0, |
BRW_SWIZZLE_XYZW, /* NOTE! */ |
WRITEMASK_XYZW); /* NOTE! */ |
} |
|
static inline struct brw_reg brw_acc_reg(void) |
{ |
return brw_vec8_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_ACCUMULATOR, |
0); |
} |
|
static inline struct brw_reg brw_notification_1_reg(void) |
{ |
return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_NOTIFICATION_COUNT, |
1, |
BRW_REGISTER_TYPE_UD, |
BRW_VERTICAL_STRIDE_0, |
BRW_WIDTH_1, |
BRW_HORIZONTAL_STRIDE_0, |
BRW_SWIZZLE_XXXX, |
WRITEMASK_X); |
} |
|
static inline struct brw_reg brw_flag_reg(void) |
{ |
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_FLAG, |
0); |
} |
|
static inline struct brw_reg brw_mask_reg(unsigned subnr) |
{ |
return brw_uw1_reg(BRW_ARCHITECTURE_REGISTER_FILE, |
BRW_ARF_MASK, |
subnr); |
} |
|
static inline struct brw_reg brw_message_reg(unsigned nr) |
{ |
assert((nr & ~(1 << 7)) < BRW_MAX_MRF); |
return brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, nr, 0); |
} |
|
static inline struct brw_reg brw_message4_reg(unsigned nr, |
int subnr) |
{ |
assert((nr & ~(1 << 7)) < BRW_MAX_MRF); |
return brw_vec4_reg(BRW_MESSAGE_REGISTER_FILE, nr, subnr); |
} |
|
/* This is almost always called with a numeric constant argument, so |
* make things easy to evaluate at compile time: |
*/ |
static inline unsigned cvt(unsigned val) |
{ |
switch (val) { |
case 0: return 0; |
case 1: return 1; |
case 2: return 2; |
case 4: return 3; |
case 8: return 4; |
case 16: return 5; |
case 32: return 6; |
} |
return 0; |
} |
|
static inline struct brw_reg __stride(struct brw_reg reg, |
unsigned vstride, |
unsigned width, |
unsigned hstride) |
{ |
reg.vstride = cvt(vstride); |
reg.width = cvt(width) - 1; |
reg.hstride = cvt(hstride); |
return reg; |
} |
|
static inline struct brw_reg vec16(struct brw_reg reg) |
{ |
return __stride(reg, 16,16,1); |
} |
|
static inline struct brw_reg vec8(struct brw_reg reg) |
{ |
return __stride(reg, 8,8,1); |
} |
|
static inline struct brw_reg vec4(struct brw_reg reg) |
{ |
return __stride(reg, 4,4,1); |
} |
|
static inline struct brw_reg vec2(struct brw_reg reg) |
{ |
return __stride(reg, 2,2,1); |
} |
|
static inline struct brw_reg vec1(struct brw_reg reg) |
{ |
return __stride(reg, 0,1,0); |
} |
|
static inline struct brw_reg get_element(struct brw_reg reg, unsigned elt) |
{ |
return vec1(__suboffset(reg, elt)); |
} |
|
static inline struct brw_reg get_element_ud(struct brw_reg reg, unsigned elt) |
{ |
return vec1(__suboffset(__retype(reg, BRW_REGISTER_TYPE_UD), elt)); |
} |
|
static inline struct brw_reg brw_swizzle(struct brw_reg reg, |
unsigned x, |
unsigned y, |
unsigned z, |
unsigned w) |
{ |
assert(reg.file != BRW_IMMEDIATE_VALUE); |
|
reg.dw1.bits.swizzle = BRW_SWIZZLE4(BRW_GET_SWZ(reg.dw1.bits.swizzle, x), |
BRW_GET_SWZ(reg.dw1.bits.swizzle, y), |
BRW_GET_SWZ(reg.dw1.bits.swizzle, z), |
BRW_GET_SWZ(reg.dw1.bits.swizzle, w)); |
return reg; |
} |
|
static inline struct brw_reg brw_swizzle1(struct brw_reg reg, |
unsigned x) |
{ |
return brw_swizzle(reg, x, x, x, x); |
} |
|
static inline struct brw_reg brw_writemask(struct brw_reg reg, |
unsigned mask) |
{ |
assert(reg.file != BRW_IMMEDIATE_VALUE); |
reg.dw1.bits.writemask &= mask; |
return reg; |
} |
|
static inline struct brw_reg brw_set_writemask(struct brw_reg reg, |
unsigned mask) |
{ |
assert(reg.file != BRW_IMMEDIATE_VALUE); |
reg.dw1.bits.writemask = mask; |
return reg; |
} |
|
static inline struct brw_reg brw_negate(struct brw_reg reg) |
{ |
reg.negate ^= 1; |
return reg; |
} |
|
static inline struct brw_reg brw_abs(struct brw_reg reg) |
{ |
reg.abs = 1; |
return reg; |
} |
|
/*********************************************************************** |
*/ |
static inline struct brw_reg brw_vec4_indirect(unsigned subnr, |
int offset) |
{ |
struct brw_reg reg = brw_vec4_grf(0, 0); |
reg.subnr = subnr; |
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; |
reg.dw1.bits.indirect_offset = offset; |
return reg; |
} |
|
static inline struct brw_reg brw_vec1_indirect(unsigned subnr, |
int offset) |
{ |
struct brw_reg reg = brw_vec1_grf(0, 0); |
reg.subnr = subnr; |
reg.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; |
reg.dw1.bits.indirect_offset = offset; |
return reg; |
} |
|
static inline struct brw_reg deref_4f(struct brw_indirect ptr, int offset) |
{ |
return brw_vec4_indirect(ptr.addr_subnr, ptr.addr_offset + offset); |
} |
|
static inline struct brw_reg deref_1f(struct brw_indirect ptr, int offset) |
{ |
return brw_vec1_indirect(ptr.addr_subnr, ptr.addr_offset + offset); |
} |
|
static inline struct brw_reg deref_4b(struct brw_indirect ptr, int offset) |
{ |
return __retype(deref_4f(ptr, offset), BRW_REGISTER_TYPE_B); |
} |
|
static inline struct brw_reg deref_1uw(struct brw_indirect ptr, int offset) |
{ |
return __retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UW); |
} |
|
static inline struct brw_reg deref_1d(struct brw_indirect ptr, int offset) |
{ |
return __retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_D); |
} |
|
static inline struct brw_reg deref_1ud(struct brw_indirect ptr, int offset) |
{ |
return __retype(deref_1f(ptr, offset), BRW_REGISTER_TYPE_UD); |
} |
|
static inline struct brw_reg get_addr_reg(struct brw_indirect ptr) |
{ |
return brw_address_reg(ptr.addr_subnr); |
} |
|
static inline struct brw_indirect brw_indirect_offset(struct brw_indirect ptr, int offset) |
{ |
ptr.addr_offset += offset; |
return ptr; |
} |
|
static inline struct brw_indirect brw_indirect(unsigned addr_subnr, int offset) |
{ |
struct brw_indirect ptr; |
ptr.addr_subnr = addr_subnr; |
ptr.addr_offset = offset; |
ptr.pad = 0; |
return ptr; |
} |
|
/** Do two brw_regs refer to the same register? */ |
static inline bool brw_same_reg(struct brw_reg r1, struct brw_reg r2) |
{ |
return r1.file == r2.file && r1.nr == r2.nr; |
} |
|
static inline struct brw_instruction *current_insn( struct brw_compile *p) |
{ |
return &p->store[p->nr_insn]; |
} |
|
static inline void brw_set_predicate_control( struct brw_compile *p, unsigned pc ) |
{ |
p->current->header.predicate_control = pc; |
} |
|
static inline void brw_set_predicate_inverse(struct brw_compile *p, bool predicate_inverse) |
{ |
p->current->header.predicate_inverse = predicate_inverse; |
} |
|
static inline void brw_set_conditionalmod( struct brw_compile *p, unsigned conditional ) |
{ |
p->current->header.destreg__conditionalmod = conditional; |
} |
|
static inline void brw_set_access_mode(struct brw_compile *p, unsigned access_mode) |
{ |
p->current->header.access_mode = access_mode; |
} |
|
static inline void brw_set_mask_control(struct brw_compile *p, unsigned value) |
{ |
p->current->header.mask_control = value; |
} |
|
static inline void brw_set_saturate(struct brw_compile *p, unsigned value) |
{ |
p->current->header.saturate = value; |
} |
|
static inline void brw_set_acc_write_control(struct brw_compile *p, unsigned value) |
{ |
if (p->gen >= 060) |
p->current->header.acc_wr_control = value; |
} |
|
void brw_pop_insn_state(struct brw_compile *p); |
void brw_push_insn_state(struct brw_compile *p); |
void brw_set_compression_control(struct brw_compile *p, enum brw_compression control); |
void brw_set_predicate_control_flag_value( struct brw_compile *p, unsigned value ); |
|
void brw_compile_init(struct brw_compile *p, int gen, void *store); |
|
void brw_set_dest(struct brw_compile *p, struct brw_instruction *insn, |
struct brw_reg dest); |
void brw_set_src0(struct brw_compile *p, struct brw_instruction *insn, |
struct brw_reg reg); |
void brw_set_src1(struct brw_compile *p, |
struct brw_instruction *insn, |
struct brw_reg reg); |
|
void gen6_resolve_implied_move(struct brw_compile *p, |
struct brw_reg *src, |
unsigned msg_reg_nr); |
|
static inline struct brw_instruction * |
brw_next_insn(struct brw_compile *p, unsigned opcode) |
{ |
struct brw_instruction *insn; |
|
assert(p->nr_insn + 1 < BRW_EU_MAX_INSN); |
|
insn = &p->store[p->nr_insn++]; |
*insn = *p->current; |
|
if (p->current->header.destreg__conditionalmod) { |
p->current->header.destreg__conditionalmod = 0; |
p->current->header.predicate_control = BRW_PREDICATE_NORMAL; |
} |
|
insn->header.opcode = opcode; |
return insn; |
} |
|
/* Helpers for regular instructions: */ |
#define ALU1(OP) \ |
static inline struct brw_instruction *brw_##OP(struct brw_compile *p, \ |
struct brw_reg dest, \ |
struct brw_reg src0) \ |
{ \ |
return brw_alu1(p, BRW_OPCODE_##OP, dest, src0); \ |
} |
|
#define ALU2(OP) \ |
static inline struct brw_instruction *brw_##OP(struct brw_compile *p, \ |
struct brw_reg dest, \ |
struct brw_reg src0, \ |
struct brw_reg src1) \ |
{ \ |
return brw_alu2(p, BRW_OPCODE_##OP, dest, src0, src1); \ |
} |
|
/* Rounding operations (other than RNDD) require two instructions - the first |
* stores a rounded value (possibly the wrong way) in the dest register, but |
* also sets a per-channel "increment bit" in the flag register. A predicated |
* add of 1.0 fixes dest to contain the desired result. |
* |
* Sandybridge and later appear to round correctly without an ADD. |
*/ |
#define ROUND(OP) \ |
static inline void brw_##OP(struct brw_compile *p, \ |
struct brw_reg dest, \ |
struct brw_reg src) \ |
{ \ |
struct brw_instruction *rnd, *add; \ |
rnd = brw_next_insn(p, BRW_OPCODE_##OP); \ |
brw_set_dest(p, rnd, dest); \ |
brw_set_src0(p, rnd, src); \ |
if (p->gen < 060) { \ |
/* turn on round-increments */ \ |
rnd->header.destreg__conditionalmod = BRW_CONDITIONAL_R; \ |
add = brw_ADD(p, dest, dest, brw_imm_f(1.0f)); \ |
add->header.predicate_control = BRW_PREDICATE_NORMAL; \ |
} \ |
} |
|
static inline struct brw_instruction *brw_alu1(struct brw_compile *p, |
unsigned opcode, |
struct brw_reg dest, |
struct brw_reg src) |
{ |
struct brw_instruction *insn = brw_next_insn(p, opcode); |
brw_set_dest(p, insn, dest); |
brw_set_src0(p, insn, src); |
return insn; |
} |
|
static inline struct brw_instruction *brw_alu2(struct brw_compile *p, |
unsigned opcode, |
struct brw_reg dest, |
struct brw_reg src0, |
struct brw_reg src1 ) |
{ |
struct brw_instruction *insn = brw_next_insn(p, opcode); |
brw_set_dest(p, insn, dest); |
brw_set_src0(p, insn, src0); |
brw_set_src1(p, insn, src1); |
return insn; |
} |
|
static inline struct brw_instruction *brw_ADD(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg src0, |
struct brw_reg src1) |
{ |
/* 6.2.2: add */ |
if (src0.type == BRW_REGISTER_TYPE_F || |
(src0.file == BRW_IMMEDIATE_VALUE && |
src0.type == BRW_REGISTER_TYPE_VF)) { |
assert(src1.type != BRW_REGISTER_TYPE_UD); |
assert(src1.type != BRW_REGISTER_TYPE_D); |
} |
|
if (src1.type == BRW_REGISTER_TYPE_F || |
(src1.file == BRW_IMMEDIATE_VALUE && |
src1.type == BRW_REGISTER_TYPE_VF)) { |
assert(src0.type != BRW_REGISTER_TYPE_UD); |
assert(src0.type != BRW_REGISTER_TYPE_D); |
} |
|
return brw_alu2(p, BRW_OPCODE_ADD, dest, src0, src1); |
} |
|
static inline struct brw_instruction *brw_MUL(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg src0, |
struct brw_reg src1) |
{ |
/* 6.32.38: mul */ |
if (src0.type == BRW_REGISTER_TYPE_D || |
src0.type == BRW_REGISTER_TYPE_UD || |
src1.type == BRW_REGISTER_TYPE_D || |
src1.type == BRW_REGISTER_TYPE_UD) { |
assert(dest.type != BRW_REGISTER_TYPE_F); |
} |
|
if (src0.type == BRW_REGISTER_TYPE_F || |
(src0.file == BRW_IMMEDIATE_VALUE && |
src0.type == BRW_REGISTER_TYPE_VF)) { |
assert(src1.type != BRW_REGISTER_TYPE_UD); |
assert(src1.type != BRW_REGISTER_TYPE_D); |
} |
|
if (src1.type == BRW_REGISTER_TYPE_F || |
(src1.file == BRW_IMMEDIATE_VALUE && |
src1.type == BRW_REGISTER_TYPE_VF)) { |
assert(src0.type != BRW_REGISTER_TYPE_UD); |
assert(src0.type != BRW_REGISTER_TYPE_D); |
} |
|
assert(src0.file != BRW_ARCHITECTURE_REGISTER_FILE || |
src0.nr != BRW_ARF_ACCUMULATOR); |
assert(src1.file != BRW_ARCHITECTURE_REGISTER_FILE || |
src1.nr != BRW_ARF_ACCUMULATOR); |
|
return brw_alu2(p, BRW_OPCODE_MUL, dest, src0, src1); |
} |
|
static inline struct brw_instruction *brw_JMPI(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg src0, |
struct brw_reg src1) |
{ |
struct brw_instruction *insn = brw_alu2(p, BRW_OPCODE_JMPI, dest, src0, src1); |
|
insn->header.execution_size = 1; |
insn->header.compression_control = BRW_COMPRESSION_NONE; |
insn->header.mask_control = BRW_MASK_DISABLE; |
|
p->current->header.predicate_control = BRW_PREDICATE_NONE; |
|
return insn; |
} |
|
|
ALU1(MOV); |
ALU2(SEL); |
ALU1(NOT); |
ALU2(AND); |
ALU2(OR); |
ALU2(XOR); |
ALU2(SHR); |
ALU2(SHL); |
ALU2(RSR); |
ALU2(RSL); |
ALU2(ASR); |
ALU1(FRC); |
ALU1(RNDD); |
ALU2(MAC); |
ALU2(MACH); |
ALU1(LZD); |
ALU2(DP4); |
ALU2(DPH); |
ALU2(DP3); |
ALU2(DP2); |
ALU2(LINE); |
ALU2(PLN); |
|
ROUND(RNDZ); |
ROUND(RNDE); |
|
#undef ALU1 |
#undef ALU2 |
#undef ROUND |
|
/* Helpers for SEND instruction */ |
void brw_set_dp_read_message(struct brw_compile *p, |
struct brw_instruction *insn, |
unsigned binding_table_index, |
unsigned msg_control, |
unsigned msg_type, |
unsigned target_cache, |
unsigned msg_length, |
unsigned response_length); |
|
void brw_set_dp_write_message(struct brw_compile *p, |
struct brw_instruction *insn, |
unsigned binding_table_index, |
unsigned msg_control, |
unsigned msg_type, |
unsigned msg_length, |
bool header_present, |
bool last_render_target, |
unsigned response_length, |
bool end_of_thread, |
bool send_commit_msg); |
|
void brw_urb_WRITE(struct brw_compile *p, |
struct brw_reg dest, |
unsigned msg_reg_nr, |
struct brw_reg src0, |
bool allocate, |
bool used, |
unsigned msg_length, |
unsigned response_length, |
bool eot, |
bool writes_complete, |
unsigned offset, |
unsigned swizzle); |
|
void brw_ff_sync(struct brw_compile *p, |
struct brw_reg dest, |
unsigned msg_reg_nr, |
struct brw_reg src0, |
bool allocate, |
unsigned response_length, |
bool eot); |
|
void brw_fb_WRITE(struct brw_compile *p, |
int dispatch_width, |
unsigned msg_reg_nr, |
struct brw_reg src0, |
unsigned msg_control, |
unsigned binding_table_index, |
unsigned msg_length, |
unsigned response_length, |
bool eot, |
bool header_present); |
|
void brw_SAMPLE(struct brw_compile *p, |
struct brw_reg dest, |
unsigned msg_reg_nr, |
struct brw_reg src0, |
unsigned binding_table_index, |
unsigned sampler, |
unsigned writemask, |
unsigned msg_type, |
unsigned response_length, |
unsigned msg_length, |
bool header_present, |
unsigned simd_mode); |
|
void brw_math_16(struct brw_compile *p, |
struct brw_reg dest, |
unsigned function, |
unsigned saturate, |
unsigned msg_reg_nr, |
struct brw_reg src, |
unsigned precision); |
|
void brw_math(struct brw_compile *p, |
struct brw_reg dest, |
unsigned function, |
unsigned saturate, |
unsigned msg_reg_nr, |
struct brw_reg src, |
unsigned data_type, |
unsigned precision); |
|
void brw_math2(struct brw_compile *p, |
struct brw_reg dest, |
unsigned function, |
struct brw_reg src0, |
struct brw_reg src1); |
|
void brw_oword_block_read(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg mrf, |
uint32_t offset, |
uint32_t bind_table_index); |
|
void brw_oword_block_read_scratch(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg mrf, |
int num_regs, |
unsigned offset); |
|
void brw_oword_block_write_scratch(struct brw_compile *p, |
struct brw_reg mrf, |
int num_regs, |
unsigned offset); |
|
void brw_dword_scattered_read(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg mrf, |
uint32_t bind_table_index); |
|
void brw_dp_READ_4_vs(struct brw_compile *p, |
struct brw_reg dest, |
unsigned location, |
unsigned bind_table_index); |
|
void brw_dp_READ_4_vs_relative(struct brw_compile *p, |
struct brw_reg dest, |
struct brw_reg addrReg, |
unsigned offset, |
unsigned bind_table_index); |
|
/* If/else/endif. Works by manipulating the execution flags on each |
* channel. |
*/ |
struct brw_instruction *brw_IF(struct brw_compile *p, |
unsigned execute_size); |
struct brw_instruction *gen6_IF(struct brw_compile *p, uint32_t conditional, |
struct brw_reg src0, struct brw_reg src1); |
|
void brw_ELSE(struct brw_compile *p); |
void brw_ENDIF(struct brw_compile *p); |
|
/* DO/WHILE loops: |
*/ |
struct brw_instruction *brw_DO(struct brw_compile *p, |
unsigned execute_size); |
|
struct brw_instruction *brw_WHILE(struct brw_compile *p, |
struct brw_instruction *patch_insn); |
|
struct brw_instruction *brw_BREAK(struct brw_compile *p, int pop_count); |
struct brw_instruction *brw_CONT(struct brw_compile *p, int pop_count); |
struct brw_instruction *gen6_CONT(struct brw_compile *p, |
struct brw_instruction *do_insn); |
/* Forward jumps: |
*/ |
void brw_land_fwd_jump(struct brw_compile *p, |
struct brw_instruction *jmp_insn); |
|
void brw_NOP(struct brw_compile *p); |
|
void brw_WAIT(struct brw_compile *p); |
|
/* Special case: there is never a destination, execution size will be |
* taken from src0: |
*/ |
void brw_CMP(struct brw_compile *p, |
struct brw_reg dest, |
unsigned conditional, |
struct brw_reg src0, |
struct brw_reg src1); |
|
void brw_print_reg(struct brw_reg reg); |
|
static inline void brw_math_invert(struct brw_compile *p, |
struct brw_reg dst, |
struct brw_reg src) |
{ |
brw_math(p, |
dst, |
BRW_MATH_FUNCTION_INV, |
BRW_MATH_SATURATE_NONE, |
0, |
src, |
BRW_MATH_PRECISION_FULL, |
BRW_MATH_DATA_VECTOR); |
} |
|
void brw_set_uip_jip(struct brw_compile *p); |
|
uint32_t brw_swap_cmod(uint32_t cmod); |
|
void brw_disasm(FILE *file, |
const struct brw_instruction *inst, |
int gen); |
|
#endif |