Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / gallium / drivers / nv30 / nv30_shader.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_FL 0 /* guess */
76 # define NV30_VP_INST_COND_LT 1
77 # define NV30_VP_INST_COND_EQ 2
78 # define NV30_VP_INST_COND_LE 3
79 # define NV30_VP_INST_COND_GT 4
80 # define NV30_VP_INST_COND_NE 5
81 # define NV30_VP_INST_COND_GE 6
82 # define NV30_VP_INST_COND_TR 7 /* guess */
83 #define NV30_VP_INST_COND_SWZ_X_SHIFT 9
84 #define NV30_VP_INST_COND_SWZ_X_MASK (0x03 << 9)
85 #define NV30_VP_INST_COND_SWZ_Y_SHIFT 7
86 #define NV30_VP_INST_COND_SWZ_Y_MASK (0x03 << 7)
87 #define NV30_VP_INST_COND_SWZ_Z_SHIFT 5
88 #define NV30_VP_INST_COND_SWZ_Z_MASK (0x03 << 5)
89 #define NV30_VP_INST_COND_SWZ_W_SHIFT 3
90 #define NV30_VP_INST_COND_SWZ_W_MASK (0x03 << 3)
91 #define NV30_VP_INST_COND_SWZ_ALL_SHIFT 3
92 #define NV30_VP_INST_COND_SWZ_ALL_MASK (0xFF << 3)
93 #define NV30_VP_INST_ADDR_SWZ_SHIFT 1
94 #define NV30_VP_INST_ADDR_SWZ_MASK (0x03 << 1)
95 #define NV30_VP_INST_SCA_OPCODEH_SHIFT 0
96 #define NV30_VP_INST_SCA_OPCODEH_MASK (0x01 << 0)
97
98 /* DWORD 1 */
99 #define NV30_VP_INST_SCA_OPCODEL_SHIFT 28
100 #define NV30_VP_INST_SCA_OPCODEL_MASK (0x0F << 28)
101 # define NV30_VP_INST_OP_NOP 0x00
102 # define NV30_VP_INST_OP_RCP 0x02
103 # define NV30_VP_INST_OP_RCC 0x03
104 # define NV30_VP_INST_OP_RSQ 0x04
105 # define NV30_VP_INST_OP_EXP 0x05
106 # define NV30_VP_INST_OP_LOG 0x06
107 # define NV30_VP_INST_OP_LIT 0x07
108 # define NV30_VP_INST_OP_BRA 0x09
109 # define NV30_VP_INST_OP_CAL 0x0B
110 # define NV30_VP_INST_OP_RET 0x0C
111 # define NV30_VP_INST_OP_LG2 0x0D
112 # define NV30_VP_INST_OP_EX2 0x0E
113 # define NV30_VP_INST_OP_SIN 0x0F
114 # define NV30_VP_INST_OP_COS 0x10
115 #define NV30_VP_INST_VEC_OPCODE_SHIFT 23
116 #define NV30_VP_INST_VEC_OPCODE_MASK (0x1F << 23)
117 # define NV30_VP_INST_OP_NOPV 0x00
118 # define NV30_VP_INST_OP_MOV 0x01
119 # define NV30_VP_INST_OP_MUL 0x02
120 # define NV30_VP_INST_OP_ADD 0x03
121 # define NV30_VP_INST_OP_MAD 0x04
122 # define NV30_VP_INST_OP_DP3 0x05
123 # define NV30_VP_INST_OP_DP4 0x07
124 # define NV30_VP_INST_OP_DPH 0x06
125 # define NV30_VP_INST_OP_DST 0x08
126 # define NV30_VP_INST_OP_MIN 0x09
127 # define NV30_VP_INST_OP_MAX 0x0A
128 # define NV30_VP_INST_OP_SLT 0x0B
129 # define NV30_VP_INST_OP_SGE 0x0C
130 # define NV30_VP_INST_OP_ARL 0x0D
131 # define NV30_VP_INST_OP_FRC 0x0E
132 # define NV30_VP_INST_OP_FLR 0x0F
133 # define NV30_VP_INST_OP_SEQ 0x10
134 # define NV30_VP_INST_OP_SFL 0x11
135 # define NV30_VP_INST_OP_SGT 0x12
136 # define NV30_VP_INST_OP_SLE 0x13
137 # define NV30_VP_INST_OP_SNE 0x14
138 # define NV30_VP_INST_OP_STR 0x15
139 # define NV30_VP_INST_OP_SSG 0x16
140 # define NV30_VP_INST_OP_ARR 0x17
141 # define NV30_VP_INST_OP_ARA 0x18
142 #define NV30_VP_INST_CONST_SRC_SHIFT 14
143 #define NV30_VP_INST_CONST_SRC_MASK (0xFF << 14)
144 #define NV30_VP_INST_INPUT_SRC_SHIFT 9 /*NV20*/
145 #define NV30_VP_INST_INPUT_SRC_MASK (0x0F << 9) /*NV20*/
146 # define NV30_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
147 # define NV30_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
148 # define NV30_VP_INST_IN_NORMAL 2
149 # define NV30_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
150 # define NV30_VP_INST_IN_COL1 4
151 # define NV30_VP_INST_IN_FOGC 5
152 # define NV30_VP_INST_IN_TC0 8
153 # define NV30_VP_INST_IN_TC(n) (8+n)
154 #define NV30_VP_INST_SRC0H_SHIFT 0 /*NV20*/
155 #define NV30_VP_INST_SRC0H_MASK (0x1FF << 0) /*NV20*/
156
157 /* Please note: the IADDR fields overlap other fields because they are used
158 * only for branch instructions. See Branching: label above
159 *
160 * DWORD 2
161 */
162 #define NV30_VP_INST_SRC0L_SHIFT 26 /*NV20*/
163 #define NV30_VP_INST_SRC0L_MASK (0x3F <<26) /* NV30_VP_SRC0_LOW_MASK << 26 */
164 #define NV30_VP_INST_SRC1_SHIFT 11 /*NV20*/
165 #define NV30_VP_INST_SRC1_MASK (0x7FFF<<11) /*NV20*/
166 #define NV30_VP_INST_SRC2H_SHIFT 0 /*NV20*/
167 #define NV30_VP_INST_SRC2H_MASK (0x7FF << 0) /* NV30_VP_SRC2_HIGH_MASK >> 4*/
168 #define NV30_VP_INST_IADDR_SHIFT 2
169 #define NV30_VP_INST_IADDR_MASK (0xF << 28) /* NV30_VP_SRC2_LOW_MASK << 28 */
170
171 /* DWORD 3 */
172 #define NV30_VP_INST_SRC2L_SHIFT 28 /*NV20*/
173 #define NV30_VP_INST_SRC2L_MASK (0x0F <<28) /*NV20*/
174 #define NV30_VP_INST_STEMP_WRITEMASK_SHIFT 24
175 #define NV30_VP_INST_STEMP_WRITEMASK_MASK (0x0F << 24)
176 #define NV30_VP_INST_VTEMP_WRITEMASK_SHIFT 20
177 #define NV30_VP_INST_VTEMP_WRITEMASK_MASK (0x0F << 20)
178 #define NV30_VP_INST_SDEST_WRITEMASK_SHIFT 16
179 #define NV30_VP_INST_SDEST_WRITEMASK_MASK (0x0F << 16)
180 #define NV30_VP_INST_VDEST_WRITEMASK_SHIFT 12 /*NV20*/
181 #define NV30_VP_INST_VDEST_WRITEMASK_MASK (0x0F << 12) /*NV20*/
182 #define NV30_VP_INST_DEST_SHIFT 2
183 #define NV30_VP_INST_DEST_MASK (0x0F << 2)
184 # define NV30_VP_INST_DEST_POS 0
185 # define NV30_VP_INST_DEST_BFC0 1
186 # define NV30_VP_INST_DEST_BFC1 2
187 # define NV30_VP_INST_DEST_COL0 3
188 # define NV30_VP_INST_DEST_COL1 4
189 # define NV30_VP_INST_DEST_FOGC 5
190 # define NV30_VP_INST_DEST_PSZ 6
191 # define NV30_VP_INST_DEST_TC(n) (8+n)
192
193 #define NV30_VP_INST_LAST (1 << 0)
194
195 /* Useful to split the source selection regs into their pieces */
196 #define NV30_VP_SRC0_HIGH_SHIFT 6
197 #define NV30_VP_SRC0_HIGH_MASK 0x00007FC0
198 #define NV30_VP_SRC0_LOW_MASK 0x0000003F
199 #define NV30_VP_SRC2_HIGH_SHIFT 4
200 #define NV30_VP_SRC2_HIGH_MASK 0x00007FF0
201 #define NV30_VP_SRC2_LOW_MASK 0x0000000F
202
203
204 /* Source-register definition - matches NV20 exactly */
205 #define NV30_VP_SRC_NEGATE (1<<14)
206 #define NV30_VP_SRC_SWZ_X_SHIFT 12
207 #define NV30_VP_SRC_REG_SWZ_X_MASK (0x03 <<12)
208 #define NV30_VP_SRC_SWZ_Y_SHIFT 10
209 #define NV30_VP_SRC_REG_SWZ_Y_MASK (0x03 <<10)
210 #define NV30_VP_SRC_SWZ_Z_SHIFT 8
211 #define NV30_VP_SRC_REG_SWZ_Z_MASK (0x03 << 8)
212 #define NV30_VP_SRC_SWZ_W_SHIFT 6
213 #define NV30_VP_SRC_REG_SWZ_W_MASK (0x03 << 6)
214 #define NV30_VP_SRC_REG_SWZ_ALL_SHIFT 6
215 #define NV30_VP_SRC_REG_SWZ_ALL_MASK (0xFF << 6)
216 #define NV30_VP_SRC_TEMP_SRC_SHIFT 2
217 #define NV30_VP_SRC_REG_TEMP_ID_MASK (0x0F << 0)
218 #define NV30_VP_SRC_REG_TYPE_SHIFT 0
219 #define NV30_VP_SRC_REG_TYPE_MASK (0x03 << 0)
220 #define NV30_VP_SRC_REG_TYPE_TEMP 1
221 #define NV30_VP_SRC_REG_TYPE_INPUT 2
222 #define NV30_VP_SRC_REG_TYPE_CONST 3 /* guess */
223
224 /*
225 * Each fragment program opcode appears to be comprised of 4 32-bit values.
226 *
227 * 0 - Opcode, output reg/mask, ATTRIB source
228 * 1 - Source 0
229 * 2 - Source 1
230 * 3 - Source 2
231 *
232 * There appears to be no special difference between result regs and temp regs.
233 * result.color == R0.xyzw
234 * result.depth == R1.z
235 * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
236 * otherwise it is set to 1.
237 *
238 * Constants are inserted directly after the instruction that uses them.
239 *
240 * It appears that it's not possible to use two input registers in one
241 * instruction as the input sourcing is done in the instruction dword
242 * and not the source selection dwords. As such instructions such as:
243 *
244 * ADD result.color, fragment.color, fragment.texcoord[0];
245 *
246 * must be split into two MOV's and then an ADD (nvidia does this) but
247 * I'm not sure why it's not just one MOV and then source the second input
248 * in the ADD instruction..
249 *
250 * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
251 * negation requires multiplication with a const.
252 *
253 * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
254 * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
255 * is implemented simply by not writing to the relevant components of the destination.
256 *
257 * Conditional execution
258 * TODO
259 *
260 * Non-native instructions:
261 * LIT
262 * LRP - MAD+MAD
263 * SUB - ADD, negate second source
264 * RSQ - LG2 + EX2
265 * POW - LG2 + MUL + EX2
266 * SCS - COS + SIN
267 * XPD
268 */
269
270 //== Opcode / Destination selection ==
271 #define NV30_FP_OP_PROGRAM_END (1 << 0)
272 #define NV30_FP_OP_OUT_REG_SHIFT 1
273 #define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
274 /* Needs to be set when writing outputs to get expected result.. */
275 #define NV30_FP_OP_OUT_REG_HALF (1 << 7)
276 #define NV30_FP_OP_COND_WRITE_ENABLE (1 << 8)
277 #define NV30_FP_OP_OUTMASK_SHIFT 9
278 #define NV30_FP_OP_OUTMASK_MASK (0xF << 9)
279 # define NV30_FP_OP_OUT_X (1<<9)
280 # define NV30_FP_OP_OUT_Y (1<<10)
281 # define NV30_FP_OP_OUT_Z (1<<11)
282 # define NV30_FP_OP_OUT_W (1<<12)
283 /* Uncertain about these, especially the input_src values.. it's possible that
284 * they can be dynamically changed.
285 */
286 #define NV30_FP_OP_INPUT_SRC_SHIFT 13
287 #define NV30_FP_OP_INPUT_SRC_MASK (15 << 13)
288 # define NV30_FP_OP_INPUT_SRC_POSITION 0x0
289 # define NV30_FP_OP_INPUT_SRC_COL0 0x1
290 # define NV30_FP_OP_INPUT_SRC_COL1 0x2
291 # define NV30_FP_OP_INPUT_SRC_FOGC 0x3
292 # define NV30_FP_OP_INPUT_SRC_TC0 0x4
293 # define NV30_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
294 #define NV30_FP_OP_TEX_UNIT_SHIFT 17
295 #define NV30_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
296 #define NV30_FP_OP_PRECISION_SHIFT 22
297 #define NV30_FP_OP_PRECISION_MASK (3 << 22)
298 # define NV30_FP_PRECISION_FP32 0
299 # define NV30_FP_PRECISION_FP16 1
300 # define NV30_FP_PRECISION_FX12 2
301 #define NV30_FP_OP_OPCODE_SHIFT 24
302 #define NV30_FP_OP_OPCODE_MASK (0x3F << 24)
303 # define NV30_FP_OP_OPCODE_NOP 0x00
304 # define NV30_FP_OP_OPCODE_MOV 0x01
305 # define NV30_FP_OP_OPCODE_MUL 0x02
306 # define NV30_FP_OP_OPCODE_ADD 0x03
307 # define NV30_FP_OP_OPCODE_MAD 0x04
308 # define NV30_FP_OP_OPCODE_DP3 0x05
309 # define NV30_FP_OP_OPCODE_DP4 0x06
310 # define NV30_FP_OP_OPCODE_DST 0x07
311 # define NV30_FP_OP_OPCODE_MIN 0x08
312 # define NV30_FP_OP_OPCODE_MAX 0x09
313 # define NV30_FP_OP_OPCODE_SLT 0x0A
314 # define NV30_FP_OP_OPCODE_SGE 0x0B
315 # define NV30_FP_OP_OPCODE_SLE 0x0C
316 # define NV30_FP_OP_OPCODE_SGT 0x0D
317 # define NV30_FP_OP_OPCODE_SNE 0x0E
318 # define NV30_FP_OP_OPCODE_SEQ 0x0F
319 # define NV30_FP_OP_OPCODE_FRC 0x10
320 # define NV30_FP_OP_OPCODE_FLR 0x11
321 # define NV30_FP_OP_OPCODE_KIL 0x12
322 # define NV30_FP_OP_OPCODE_PK4B 0x13
323 # define NV30_FP_OP_OPCODE_UP4B 0x14
324 # define NV30_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
325 # define NV30_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
326 # define NV30_FP_OP_OPCODE_TEX 0x17
327 # define NV30_FP_OP_OPCODE_TXP 0x18
328 # define NV30_FP_OP_OPCODE_TXD 0x19
329 # define NV30_FP_OP_OPCODE_RCP 0x1A
330 # define NV30_FP_OP_OPCODE_RSQ 0x1B
331 # define NV30_FP_OP_OPCODE_EX2 0x1C
332 # define NV30_FP_OP_OPCODE_LG2 0x1D
333 # define NV30_FP_OP_OPCODE_LIT 0x1E
334 # define NV30_FP_OP_OPCODE_LRP 0x1F
335 # define NV30_FP_OP_OPCODE_STR 0x20
336 # define NV30_FP_OP_OPCODE_SFL 0x21
337 # define NV30_FP_OP_OPCODE_COS 0x22
338 # define NV30_FP_OP_OPCODE_SIN 0x23
339 # define NV30_FP_OP_OPCODE_PK2H 0x24
340 # define NV30_FP_OP_OPCODE_UP2H 0x25
341 # define NV30_FP_OP_OPCODE_POW 0x26
342 # define NV30_FP_OP_OPCODE_PK4UB 0x27
343 # define NV30_FP_OP_OPCODE_UP4UB 0x28
344 # define NV30_FP_OP_OPCODE_PK2US 0x29
345 # define NV30_FP_OP_OPCODE_UP2US 0x2A
346 # define NV30_FP_OP_OPCODE_DP2A 0x2E
347 # define NV30_FP_OP_OPCODE_TXB 0x31
348 # define NV30_FP_OP_OPCODE_RFL 0x36
349 # define NV30_FP_OP_OPCODE_DIV 0x3A
350 #define NV30_FP_OP_OUT_SAT (1 << 31)
351
352 /* high order bits of SRC0 */
353 #define NV30_FP_OP_OUT_ABS (1 << 29)
354 #define NV30_FP_OP_COND_SWZ_W_SHIFT 27
355 #define NV30_FP_OP_COND_SWZ_W_MASK (3 << 27)
356 #define NV30_FP_OP_COND_SWZ_Z_SHIFT 25
357 #define NV30_FP_OP_COND_SWZ_Z_MASK (3 << 25)
358 #define NV30_FP_OP_COND_SWZ_Y_SHIFT 23
359 #define NV30_FP_OP_COND_SWZ_Y_MASK (3 << 23)
360 #define NV30_FP_OP_COND_SWZ_X_SHIFT 21
361 #define NV30_FP_OP_COND_SWZ_X_MASK (3 << 21)
362 #define NV30_FP_OP_COND_SWZ_ALL_SHIFT 21
363 #define NV30_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
364 #define NV30_FP_OP_COND_SHIFT 18
365 #define NV30_FP_OP_COND_MASK (0x07 << 18)
366 # define NV30_FP_OP_COND_FL 0
367 # define NV30_FP_OP_COND_LT 1
368 # define NV30_FP_OP_COND_EQ 2
369 # define NV30_FP_OP_COND_LE 3
370 # define NV30_FP_OP_COND_GT 4
371 # define NV30_FP_OP_COND_NE 5
372 # define NV30_FP_OP_COND_GE 6
373 # define NV30_FP_OP_COND_TR 7
374
375 /* high order bits of SRC1 */
376 #define NV30_FP_OP_DST_SCALE_SHIFT 28
377 #define NV30_FP_OP_DST_SCALE_MASK (3 << 28)
378 #define NV30_FP_OP_DST_SCALE_1X 0
379 #define NV30_FP_OP_DST_SCALE_2X 1
380 #define NV30_FP_OP_DST_SCALE_4X 2
381 #define NV30_FP_OP_DST_SCALE_8X 3
382 #define NV30_FP_OP_DST_SCALE_INV_2X 5
383 #define NV30_FP_OP_DST_SCALE_INV_4X 6
384 #define NV30_FP_OP_DST_SCALE_INV_8X 7
385
386
387 /* high order bits of SRC2 */
388 #define NV30_FP_OP_INDEX_INPUT (1 << 30)
389
390 //== Register selection ==
391 #define NV30_FP_REG_TYPE_SHIFT 0
392 #define NV30_FP_REG_TYPE_MASK (3 << 0)
393 # define NV30_FP_REG_TYPE_TEMP 0
394 # define NV30_FP_REG_TYPE_INPUT 1
395 # define NV30_FP_REG_TYPE_CONST 2
396 #define NV30_FP_REG_SRC_SHIFT 2 /* uncertain */
397 #define NV30_FP_REG_SRC_MASK (31 << 2)
398 #define NV30_FP_REG_SRC_HALF (1 << 8)
399 #define NV30_FP_REG_SWZ_ALL_SHIFT 9
400 #define NV30_FP_REG_SWZ_ALL_MASK (255 << 9)
401 #define NV30_FP_REG_SWZ_X_SHIFT 9
402 #define NV30_FP_REG_SWZ_X_MASK (3 << 9)
403 #define NV30_FP_REG_SWZ_Y_SHIFT 11
404 #define NV30_FP_REG_SWZ_Y_MASK (3 << 11)
405 #define NV30_FP_REG_SWZ_Z_SHIFT 13
406 #define NV30_FP_REG_SWZ_Z_MASK (3 << 13)
407 #define NV30_FP_REG_SWZ_W_SHIFT 15
408 #define NV30_FP_REG_SWZ_W_MASK (3 << 15)
409 # define NV30_FP_SWIZZLE_X 0
410 # define NV30_FP_SWIZZLE_Y 1
411 # define NV30_FP_SWIZZLE_Z 2
412 # define NV30_FP_SWIZZLE_W 3
413 #define NV30_FP_REG_NEGATE (1 << 17)
414
415 #define NV30SR_NONE 0
416 #define NV30SR_OUTPUT 1
417 #define NV30SR_INPUT 2
418 #define NV30SR_TEMP 3
419 #define NV30SR_CONST 4
420
421 struct nv30_sreg {
422 int type;
423 int index;
424
425 int dst_scale;
426
427 int negate;
428 int abs;
429 int swz[4];
430
431 int cc_update;
432 int cc_update_reg;
433 int cc_test;
434 int cc_test_reg;
435 int cc_swz[4];
436 };
437
438 static INLINE struct nv30_sreg
439 nv30_sr(int type, int index)
440 {
441 struct nv30_sreg temp = {
442 .type = type,
443 .index = index,
444 .dst_scale = DEF_SCALE,
445 .abs = 0,
446 .negate = 0,
447 .swz = { 0, 1, 2, 3 },
448 .cc_update = 0,
449 .cc_update_reg = 0,
450 .cc_test = DEF_CTEST,
451 .cc_test_reg = 0,
452 .cc_swz = { 0, 1, 2, 3 },
453 };
454 return temp;
455 }
456
457 static INLINE struct nv30_sreg
458 nv30_sr_swz(struct nv30_sreg src, int x, int y, int z, int w)
459 {
460 struct nv30_sreg dst = src;
461
462 dst.swz[SWZ_X] = src.swz[x];
463 dst.swz[SWZ_Y] = src.swz[y];
464 dst.swz[SWZ_Z] = src.swz[z];
465 dst.swz[SWZ_W] = src.swz[w];
466 return dst;
467 }
468
469 static INLINE struct nv30_sreg
470 nv30_sr_neg(struct nv30_sreg src)
471 {
472 src.negate = !src.negate;
473 return src;
474 }
475
476 static INLINE struct nv30_sreg
477 nv30_sr_abs(struct nv30_sreg src)
478 {
479 src.abs = 1;
480 return src;
481 }
482
483 static INLINE struct nv30_sreg
484 nv30_sr_scale(struct nv30_sreg src, int scale)
485 {
486 src.dst_scale = scale;
487 return src;
488 }
489
490 #endif