Merge branch '7.8'
[mesa.git] / src / gallium / drivers / nvfx / nv30_vertprog.h
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 #define NV30_VP_INST_ADDR_REG_SELECT_1 (1 << 24)
64 #define NV30_VP_INST_SRC2_ABS (1 << 23) /* guess */
65 #define NV30_VP_INST_SRC1_ABS (1 << 22) /* guess */
66 #define NV30_VP_INST_SRC0_ABS (1 << 21) /* guess */
67 #define NV30_VP_INST_VEC_RESULT (1 << 20)
68 #define NV30_VP_INST_DEST_TEMP_ID_SHIFT 16
69 #define NV30_VP_INST_DEST_TEMP_ID_MASK (0x0F << 16)
70 #define NV30_VP_INST_COND_UPDATE_ENABLE (1<<15)
71 #define NV30_VP_INST_VEC_DEST_TEMP_MASK (0xF << 16)
72 #define NV30_VP_INST_COND_TEST_ENABLE (1<<14)
73 #define NV30_VP_INST_COND_SHIFT 11
74 #define NV30_VP_INST_COND_MASK (0x07 << 11)
75 #define NV30_VP_INST_COND_SWZ_X_SHIFT 9
76 #define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9)
77 #define NV30_VP_INST_COND_SWZ_Y_SHIFT 7
78 #define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7)
79 #define NV30_VP_INST_COND_SWZ_Z_SHIFT 5
80 #define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5)
81 #define NV30_VP_INST_COND_SWZ_W_SHIFT 3
82 #define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3)
83 #define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3
84 #define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3)
85 #define NV30_VP_INST_ADDR_SWZ_SHIFT 1
86 #define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1)
87 #define NV30_VP_INST_SCA_OPCODEH_SHIFT 0
88 #define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0)
89
90 /* DWORD 1 */
91 #define NV30_VP_INST_SCA_OPCODEL_SHIFT 28
92 #define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28)
93 #define NV30_VP_INST_VEC_OPCODE_SHIFT 23
94 #define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23)
95 #define NV30_VP_INST_CONST_SRC_SHIFT 14
96 #define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14)
97 #define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/
98 #define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/
99 #define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/
100 #define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/
101
102 /* Please note: the IADDR fields overlap other fields because they are used
103 * only for branch instructions. See Branching: label above
104 *
105 * DWORD 2
106 */
107 #define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/
108 #define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /* NV30_VP_SRC0_LOW_MASK << 26 */
109 #define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/
110 #define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/
111 #define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/
112 #define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /* NV30_VP_SRC2_HIGH_MASK >> 4*/
113 #define NV30_VP_INST_IADDR_SHIFT 2
114 #define NV30_VP_INST_IADDR_MASK (0xF << 28) /* NV30_VP_SRC2_LOW_MASK << 28 */
115
116 /* DWORD 3 */
117 #define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/
118 #define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/
119 #define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24
120 #define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24)
121 #define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20
122 #define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20)
123 #define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16
124 #define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16)
125 #define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/
126 #define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/
127 #define NV30_VP_INST_DEST_SHIFT 2
128 #define NV30_VP_INST_DEST_MASK (0x0F << 2)
129 # define NV30_VP_INST_DEST_POS 0
130 # define NV30_VP_INST_DEST_BFC0 1
131 # define NV30_VP_INST_DEST_BFC1 2
132 # define NV30_VP_INST_DEST_COL0 3
133 # define NV30_VP_INST_DEST_COL1 4
134 # define NV30_VP_INST_DEST_FOGC 5
135 # define NV30_VP_INST_DEST_PSZ 6
136 # define NV30_VP_INST_DEST_TC(n) (8+n)
137
138 /* Useful to split the source selection regs into their pieces */
139 #define NV30_VP_SRC0_HIGH_SHIFT 6
140 #define NV30_VP_SRC0_HIGH_MASK 0x00007FC0
141 #define NV30_VP_SRC0_LOW_MASK 0x0000003F
142 #define NV30_VP_SRC2_HIGH_SHIFT 4
143 #define NV30_VP_SRC2_HIGH_MASK 0x00007FF0
144 #define NV30_VP_SRC2_LOW_MASK 0x0000000F
145
146
147 /* Source-register definition - matches NV20 exactly */
148 #define NV30_VP_SRC_NEGATE (1<<14)
149 #define NV30_VP_SRC_SWZ_X_SHIFT 12
150 #define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
151 #define NV30_VP_SRC_SWZ_Y_SHIFT 10
152 #define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
153 #define NV30_VP_SRC_SWZ_Z_SHIFT 8
154 #define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
155 #define NV30_VP_SRC_SWZ_W_SHIFT 6
156 #define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
157 #define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6
158 #define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
159 #define NV30_VP_SRC_TEMP_SRC_SHIFT 2
160 #define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
161 #define NV30_VP_SRC_REG_TYPE_SHIFT 0
162 #define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0)
163 #define NV30_VP_SRC_REG_TYPE_TEMP 1
164 #define NV30_VP_SRC_REG_TYPE_INPUT 2
165 #define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */
166
167 #include "nvfx_shader.h"
168
169 #endif