1 #ifndef __NV30_SHADER_H__ 2 #define __NV30_SHADER_H__ 3 4 /* Vertex programs instruction set 5 * 6 * 128bit opcodes, split into 4 32-bit ones for ease of use. 7 * 8 * Non-native instructions 9 * ABS - MOV + NV40_VP_INST0_DEST_ABS 10 * POW - EX2 + MUL + LG2 11 * SUB - ADD, second source negated 12 * SWZ - MOV 13 * XPD - 14 * 15 * Register access 16 * - Only one INPUT can be accessed per-instruction (move extras into TEMPs) 17 * - Only one CONST can be accessed per-instruction (move extras into TEMPs) 18 * 19 * Relative Addressing 20 * According to the value returned for 21 * MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 22 * 23 * there are only two address registers available. The destination in the 24 * ARL instruction is set to TEMP <n> (The temp isn't actually written). 25 * 26 * When using vanilla ARB_v_p, the proprietary driver will squish both the 27 * available ADDRESS regs into the first hardware reg in the X and Y 28 * components. 29 * 30 * To use an address reg as an index into consts, the CONST_SRC is set to 31 * (const_base + offset) and INDEX_CONST is set. 32 * 33 * To access the second address reg use ADDR_REG_SELECT_1. A particular 34 * component of the address regs is selected with ADDR_SWZ. 35 * 36 * Only one address register can be accessed per instruction. 37 * 38 * Conditional execution (see NV_vertex_program{2,3} for details) Conditional 39 * execution of an instruction is enabled by setting COND_TEST_ENABLE, and 40 * selecting the condition which will allow the test to pass with 41 * COND_{FL,LT,...}. It is possible to swizzle the values in the condition 42 * register, which allows for testing against an individual component. 43 * 44 * Branching: 45 * 46 * The BRA/CAL instructions seem to follow a slightly different opcode 47 * layout. The destination instruction ID (IADDR) overlaps a source field. 48 * Instruction ID's seem to be numbered based on the UPLOAD_FROM_ID FIFO 49 * command, and is incremented automatically on each UPLOAD_INST FIFO 50 * command. 51 * 52 * Conditional branching is achieved by using the condition tests described 53 * above. There doesn't appear to be dedicated looping instructions, but 54 * this can be done using a temp reg + conditional branching. 55 * 56 * Subroutines may be uploaded before the main program itself, but the first 57 * executed instruction is determined by the PROGRAM_START_ID FIFO command. 58 * 59 */ 60 61 /* DWORD 0 */ 62 63 /* guess that this is the same as nv40 */ 64 #define NV30_VP_INST_INDEX_INPUT (1 << 27) 65 66 #define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24) 67 #define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */ 68 #define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */ 69 #define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */ 70 #define NV30_VP_INST_VEC_RESULT (1 << 20) 71 #define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16 72 #define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16) 73 #define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15) 74 #define NV30_VP_INST_VEC_DEST_TEMP_MASK (0x1F << 16) 75 #define NV30_VP_INST_COND_TEST_ENABLE (1<<14) 76 #define NV30_VP_INST_COND_SHIFT 11 77 #define NV30_VP_INST_COND_MASK (0x07 << 11) 78 #define NV30_VP_INST_COND_SWZ_X_SHIFT 9 79 #define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9) 80 #define NV30_VP_INST_COND_SWZ_Y_SHIFT 7 81 #define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7) 82 #define NV30_VP_INST_COND_SWZ_Z_SHIFT 5 83 #define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5) 84 #define NV30_VP_INST_COND_SWZ_W_SHIFT 3 85 #define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3) 86 #define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3 87 #define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3) 88 #define NV30_VP_INST_ADDR_SWZ_SHIFT 1 89 #define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1) 90 #define NV30_VP_INST_SCA_OPCODEH_SHIFT 0 91 #define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0) 92 93 /* DWORD 1 */ 94 #define NV30_VP_INST_SCA_OPCODEL_SHIFT 28 95 #define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28) 96 #define NV30_VP_INST_VEC_OPCODE_SHIFT 23 97 #define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23) 98 #define NV30_VP_INST_CONST_SRC_SHIFT 14 99 #define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14) 100 #define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/ 101 #define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/ 102 #define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/ 103 #define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/ 104 105 /* Please note: the IADDR fields overlap other fields because they are used 106 * only for branch instructions. See Branching: label above 107 * 108 * DWORD 2 109 */ 110 #define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/ 111 #define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /* NV30_VP_SRC0_LOW_MASK << 26 */ 112 #define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/ 113 #define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/ 114 #define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/ 115 #define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /* NV30_VP_SRC2_HIGH_MASK >> 4*/ 116 #define NV30_VP_INST_IADDR_SHIFT 2 117 #define NV30_VP_INST_IADDR_MASK (0x1FF << 2) /* NV30_VP_SRC2_LOW_MASK << 28 */ 118 119 /* DWORD 3 */ 120 #define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/ 121 #define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/ 122 #define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24 123 #define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24) 124 #define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20 125 #define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20) 126 #define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16 127 #define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16) 128 #define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/ 129 #define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/ 130 #define NV30_VP_INST_DEST_SHIFT 2 131 #define NV30_VP_INST_DEST_MASK (0x1F << 2) 132 # define NV30_VP_INST_DEST_POS 0 133 # define NV30_VP_INST_DEST_BFC0 1 134 # define NV30_VP_INST_DEST_BFC1 2 135 # define NV30_VP_INST_DEST_COL0 3 136 # define NV30_VP_INST_DEST_COL1 4 137 # define NV30_VP_INST_DEST_FOGC 5 138 # define NV30_VP_INST_DEST_PSZ 6 139 # define NV30_VP_INST_DEST_TC(n) (8+(n)) 140 # define NV30_VP_INST_DEST_CLP(n) (17 + (n)) 141 142 /* guess that this is the same as nv40 */ 143 #define NV30_VP_INST_INDEX_CONST (1 << 1) 144 145 /* Useful to split the source selection regs into their pieces */ 146 #define NV30_VP_SRC0_HIGH_SHIFT 6 147 #define NV30_VP_SRC0_HIGH_MASK 0x00007FC0 148 #define NV30_VP_SRC0_LOW_MASK 0x0000003F 149 #define NV30_VP_SRC2_HIGH_SHIFT 4 150 #define NV30_VP_SRC2_HIGH_MASK 0x00007FF0 151 #define NV30_VP_SRC2_LOW_MASK 0x0000000F 152 153 154 /* Source-register definition - matches NV20 exactly */ 155 #define NV30_VP_SRC_NEGATE (1<<14) 156 #define NV30_VP_SRC_SWZ_X_SHIFT 12 157 #define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12) 158 #define NV30_VP_SRC_SWZ_Y_SHIFT 10 159 #define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10) 160 #define NV30_VP_SRC_SWZ_Z_SHIFT 8 161 #define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8) 162 #define NV30_VP_SRC_SWZ_W_SHIFT 6 163 #define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6) 164 #define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6 165 #define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6) 166 #define NV30_VP_SRC_TEMP_SRC_SHIFT 2 167 #define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0) 168 #define NV30_VP_SRC_REG_TYPE_SHIFT 0 169 #define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0) 170 #define NV30_VP_SRC_REG_TYPE_TEMP 1 171 #define NV30_VP_SRC_REG_TYPE_INPUT 2 172 #define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */ 173 174 #include "nvfx_shader.h" 175 176 #endif 177