Merge remote branch 'origin/7.8'
[mesa.git] / src / gallium / drivers / nvfx / nvfx_shader.h
1 #ifndef __NVFX_SHADER_H__
2 #define __NVFX_SHADER_H__
3
4 /* this will resolve to either the NV30 or the NV40 version
5 * depending on the current hardware */
6 /* unusual, but very fast and compact method */
7 #define NVFX_VP(c) ((NV30_VP_##c) + (nvfx->is_nv4x & ((NV40_VP_##c) - (NV30_VP_##c))))
8
9 #define NVFX_VP_INST_SLOT_VEC 0
10 #define NVFX_VP_INST_SLOT_SCA 1
11
12 #define NVFX_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
13 #define NVFX_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
14 #define NVFX_VP_INST_IN_NORMAL 2
15 #define NVFX_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
16 #define NVFX_VP_INST_IN_COL1 4
17 #define NVFX_VP_INST_IN_FOGC 5
18 #define NVFX_VP_INST_IN_TC0 8
19 #define NVFX_VP_INST_IN_TC(n) (8+n)
20
21 #define NVFX_VP_INST_SCA_OP_NOP 0x00
22 #define NVFX_VP_INST_SCA_OP_MOV 0x01
23 #define NVFX_VP_INST_SCA_OP_RCP 0x02
24 #define NVFX_VP_INST_SCA_OP_RCC 0x03
25 #define NVFX_VP_INST_SCA_OP_RSQ 0x04
26 #define NVFX_VP_INST_SCA_OP_EXP 0x05
27 #define NVFX_VP_INST_SCA_OP_LOG 0x06
28 #define NVFX_VP_INST_SCA_OP_LIT 0x07
29 #define NVFX_VP_INST_SCA_OP_BRA 0x09
30 #define NVFX_VP_INST_SCA_OP_CAL 0x0B
31 #define NVFX_VP_INST_SCA_OP_RET 0x0C
32 #define NVFX_VP_INST_SCA_OP_LG2 0x0D
33 #define NVFX_VP_INST_SCA_OP_EX2 0x0E
34 #define NVFX_VP_INST_SCA_OP_SIN 0x0F
35 #define NVFX_VP_INST_SCA_OP_COS 0x10
36
37 #define NV40_VP_INST_SCA_OP_PUSHA 0x13
38 #define NV40_VP_INST_SCA_OP_POPA 0x14
39
40 #define NVFX_VP_INST_VEC_OP_NOP 0x00
41 #define NVFX_VP_INST_VEC_OP_MOV 0x01
42 #define NVFX_VP_INST_VEC_OP_MUL 0x02
43 #define NVFX_VP_INST_VEC_OP_ADD 0x03
44 #define NVFX_VP_INST_VEC_OP_MAD 0x04
45 #define NVFX_VP_INST_VEC_OP_DP3 0x05
46 #define NVFX_VP_INST_VEC_OP_DPH 0x06
47 #define NVFX_VP_INST_VEC_OP_DP4 0x07
48 #define NVFX_VP_INST_VEC_OP_DST 0x08
49 #define NVFX_VP_INST_VEC_OP_MIN 0x09
50 #define NVFX_VP_INST_VEC_OP_MAX 0x0A
51 #define NVFX_VP_INST_VEC_OP_SLT 0x0B
52 #define NVFX_VP_INST_VEC_OP_SGE 0x0C
53 #define NVFX_VP_INST_VEC_OP_ARL 0x0D
54 #define NVFX_VP_INST_VEC_OP_FRC 0x0E
55 #define NVFX_VP_INST_VEC_OP_FLR 0x0F
56 #define NVFX_VP_INST_VEC_OP_SEQ 0x10
57 #define NVFX_VP_INST_VEC_OP_SFL 0x11
58 #define NVFX_VP_INST_VEC_OP_SGT 0x12
59 #define NVFX_VP_INST_VEC_OP_SLE 0x13
60 #define NVFX_VP_INST_VEC_OP_SNE 0x14
61 #define NVFX_VP_INST_VEC_OP_STR 0x15
62 #define NVFX_VP_INST_VEC_OP_SSG 0x16
63 #define NVFX_VP_INST_VEC_OP_ARR 0x17
64 #define NVFX_VP_INST_VEC_OP_ARA 0x18
65
66 #define NV40_VP_INST_VEC_OP_TXL 0x19
67
68 /* DWORD 3 */
69 #define NVFX_VP_INST_LAST (1 << 0)
70
71 /*
72 * Each fragment program opcode appears to be comprised of 4 32-bit values.
73 *
74 * 0 - Opcode, output reg/mask, ATTRIB source
75 * 1 - Source 0
76 * 2 - Source 1
77 * 3 - Source 2
78 *
79 * There appears to be no special difference between result regs and temp regs.
80 * result.color == R0.xyzw
81 * result.depth == R1.z
82 * When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
83 * otherwise it is set to 1.
84 *
85 * Constants are inserted directly after the instruction that uses them.
86 *
87 * It appears that it's not possible to use two input registers in one
88 * instruction as the input sourcing is done in the instruction dword
89 * and not the source selection dwords. As such instructions such as:
90 *
91 * ADD result.color, fragment.color, fragment.texcoord[0];
92 *
93 * must be split into two MOV's and then an ADD (nvidia does this) but
94 * I'm not sure why it's not just one MOV and then source the second input
95 * in the ADD instruction..
96 *
97 * Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
98 * negation requires multiplication with a const.
99 *
100 * Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
101 * The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
102 * is implemented simply by not writing to the relevant components of the destination.
103 *
104 * Conditional execution
105 * TODO
106 *
107 * Non-native instructions:
108 * LIT
109 * LRP - MAD+MAD
110 * SUB - ADD, negate second source
111 * RSQ - LG2 + EX2
112 * POW - LG2 + MUL + EX2
113 * SCS - COS + SIN
114 * XPD
115 *
116 * NV40 Looping
117 * Loops appear to be fairly expensive on NV40 at least, the proprietary
118 * driver goes to a lot of effort to avoid using the native looping
119 * instructions. If the total number of *executed* instructions between
120 * REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
121 * The maximum loop count is 255.
122 *
123 */
124
125 //== Opcode / Destination selection ==
126 #define NVFX_FP_OP_PROGRAM_END (1 << 0)
127 #define NVFX_FP_OP_OUT_REG_SHIFT 1
128 #define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
129 #define NV40_FP_OP_OUT_REG_MASK (63 << 1)
130 /* Needs to be set when writing outputs to get expected result.. */
131 #define NVFX_FP_OP_OUT_REG_HALF (1 << 7)
132 #define NVFX_FP_OP_COND_WRITE_ENABLE (1 << 8)
133 #define NVFX_FP_OP_OUTMASK_SHIFT 9
134 #define NVFX_FP_OP_OUTMASK_MASK (0xF << 9)
135 # define NVFX_FP_OP_OUT_X (1<<9)
136 # define NVFX_FP_OP_OUT_Y (1<<10)
137 # define NVFX_FP_OP_OUT_Z (1<<11)
138 # define NVFX_FP_OP_OUT_W (1<<12)
139 /* Uncertain about these, especially the input_src values.. it's possible that
140 * they can be dynamically changed.
141 */
142 #define NVFX_FP_OP_INPUT_SRC_SHIFT 13
143 #define NVFX_FP_OP_INPUT_SRC_MASK (15 << 13)
144 # define NVFX_FP_OP_INPUT_SRC_POSITION 0x0
145 # define NVFX_FP_OP_INPUT_SRC_COL0 0x1
146 # define NVFX_FP_OP_INPUT_SRC_COL1 0x2
147 # define NVFX_FP_OP_INPUT_SRC_FOGC 0x3
148 # define NVFX_FP_OP_INPUT_SRC_TC0 0x4
149 # define NVFX_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
150 # define NV40_FP_OP_INPUT_SRC_FACING 0xE
151 #define NVFX_FP_OP_TEX_UNIT_SHIFT 17
152 #define NVFX_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
153 #define NVFX_FP_OP_PRECISION_SHIFT 22
154 #define NVFX_FP_OP_PRECISION_MASK (3 << 22)
155 # define NVFX_FP_PRECISION_FP32 0
156 # define NVFX_FP_PRECISION_FP16 1
157 # define NVFX_FP_PRECISION_FX12 2
158 #define NVFX_FP_OP_OPCODE_SHIFT 24
159 #define NVFX_FP_OP_OPCODE_MASK (0x3F << 24)
160 /* NV30/NV40 fragment program opcodes */
161 #define NVFX_FP_OP_OPCODE_NOP 0x00
162 #define NVFX_FP_OP_OPCODE_MOV 0x01
163 #define NVFX_FP_OP_OPCODE_MUL 0x02
164 #define NVFX_FP_OP_OPCODE_ADD 0x03
165 #define NVFX_FP_OP_OPCODE_MAD 0x04
166 #define NVFX_FP_OP_OPCODE_DP3 0x05
167 #define NVFX_FP_OP_OPCODE_DP4 0x06
168 #define NVFX_FP_OP_OPCODE_DST 0x07
169 #define NVFX_FP_OP_OPCODE_MIN 0x08
170 #define NVFX_FP_OP_OPCODE_MAX 0x09
171 #define NVFX_FP_OP_OPCODE_SLT 0x0A
172 #define NVFX_FP_OP_OPCODE_SGE 0x0B
173 #define NVFX_FP_OP_OPCODE_SLE 0x0C
174 #define NVFX_FP_OP_OPCODE_SGT 0x0D
175 #define NVFX_FP_OP_OPCODE_SNE 0x0E
176 #define NVFX_FP_OP_OPCODE_SEQ 0x0F
177 #define NVFX_FP_OP_OPCODE_FRC 0x10
178 #define NVFX_FP_OP_OPCODE_FLR 0x11
179 #define NVFX_FP_OP_OPCODE_KIL 0x12
180 #define NVFX_FP_OP_OPCODE_PK4B 0x13
181 #define NVFX_FP_OP_OPCODE_UP4B 0x14
182 #define NVFX_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
183 #define NVFX_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
184 #define NVFX_FP_OP_OPCODE_TEX 0x17
185 #define NVFX_FP_OP_OPCODE_TXP 0x18
186 #define NVFX_FP_OP_OPCODE_TXD 0x19
187 #define NVFX_FP_OP_OPCODE_RCP 0x1A
188 #define NVFX_FP_OP_OPCODE_EX2 0x1C
189 #define NVFX_FP_OP_OPCODE_LG2 0x1D
190 #define NVFX_FP_OP_OPCODE_STR 0x20
191 #define NVFX_FP_OP_OPCODE_SFL 0x21
192 #define NVFX_FP_OP_OPCODE_COS 0x22
193 #define NVFX_FP_OP_OPCODE_SIN 0x23
194 #define NVFX_FP_OP_OPCODE_PK2H 0x24
195 #define NVFX_FP_OP_OPCODE_UP2H 0x25
196 #define NVFX_FP_OP_OPCODE_PK4UB 0x27
197 #define NVFX_FP_OP_OPCODE_UP4UB 0x28
198 #define NVFX_FP_OP_OPCODE_PK2US 0x29
199 #define NVFX_FP_OP_OPCODE_UP2US 0x2A
200 #define NVFX_FP_OP_OPCODE_DP2A 0x2E
201 #define NVFX_FP_OP_OPCODE_TXB 0x31
202 #define NVFX_FP_OP_OPCODE_DIV 0x3A
203
204 /* NV30 only fragment program opcodes */
205 #define NVFX_FP_OP_OPCODE_RSQ_NV30 0x1B
206 #define NVFX_FP_OP_OPCODE_LIT_NV30 0x1E
207 #define NVFX_FP_OP_OPCODE_LRP_NV30 0x1F
208 #define NVFX_FP_OP_OPCODE_POW_NV30 0x26
209 #define NVFX_FP_OP_OPCODE_RFL_NV30 0x36
210
211 /* NV40 only fragment program opcodes */
212 #define NVFX_FP_OP_OPCODE_TXL_NV40 0x2F
213 /* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
214 #define NV40_FP_OP_BRA_OPCODE_BRK 0x0
215 #define NV40_FP_OP_BRA_OPCODE_CAL 0x1
216 #define NV40_FP_OP_BRA_OPCODE_IF 0x2
217 #define NV40_FP_OP_BRA_OPCODE_LOOP 0x3
218 #define NV40_FP_OP_BRA_OPCODE_REP 0x4
219 #define NV40_FP_OP_BRA_OPCODE_RET 0x5
220
221 #define NVFX_FP_OP_OUT_SAT (1 << 31)
222
223 /* high order bits of SRC0 */
224 #define NVFX_FP_OP_OUT_ABS (1 << 29)
225 #define NVFX_FP_OP_COND_SWZ_W_SHIFT 27
226 #define NVFX_FP_OP_COND_SWZ_W_MASK (3 << 27)
227 #define NVFX_FP_OP_COND_SWZ_Z_SHIFT 25
228 #define NVFX_FP_OP_COND_SWZ_Z_MASK (3 << 25)
229 #define NVFX_FP_OP_COND_SWZ_Y_SHIFT 23
230 #define NVFX_FP_OP_COND_SWZ_Y_MASK (3 << 23)
231 #define NVFX_FP_OP_COND_SWZ_X_SHIFT 21
232 #define NVFX_FP_OP_COND_SWZ_X_MASK (3 << 21)
233 #define NVFX_FP_OP_COND_SWZ_ALL_SHIFT 21
234 #define NVFX_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
235 #define NVFX_FP_OP_COND_SHIFT 18
236 #define NVFX_FP_OP_COND_MASK (0x07 << 18)
237 # define NVFX_FP_OP_COND_FL 0
238 # define NVFX_FP_OP_COND_LT 1
239 # define NVFX_FP_OP_COND_EQ 2
240 # define NVFX_FP_OP_COND_LE 3
241 # define NVFX_FP_OP_COND_GT 4
242 # define NVFX_FP_OP_COND_NE 5
243 # define NVFX_FP_OP_COND_GE 6
244 # define NVFX_FP_OP_COND_TR 7
245
246 /* high order bits of SRC1 */
247 #define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)
248 #define NVFX_FP_OP_DST_SCALE_SHIFT 28
249 #define NVFX_FP_OP_DST_SCALE_MASK (3 << 28)
250 #define NVFX_FP_OP_DST_SCALE_1X 0
251 #define NVFX_FP_OP_DST_SCALE_2X 1
252 #define NVFX_FP_OP_DST_SCALE_4X 2
253 #define NVFX_FP_OP_DST_SCALE_8X 3
254 #define NVFX_FP_OP_DST_SCALE_INV_2X 5
255 #define NVFX_FP_OP_DST_SCALE_INV_4X 6
256 #define NVFX_FP_OP_DST_SCALE_INV_8X 7
257
258 /* SRC1 LOOP */
259 #define NV40_FP_OP_LOOP_INCR_SHIFT 19
260 #define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
261 #define NV40_FP_OP_LOOP_INDEX_SHIFT 10
262 #define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
263 #define NV40_FP_OP_LOOP_COUNT_SHIFT 2
264 #define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
265
266 /* SRC1 IF */
267 #define NV40_FP_OP_ELSE_ID_SHIFT 2
268 #define NV40_FP_OP_ELSE_ID_MASK (0xFF << 2)
269
270 /* SRC1 CAL */
271 #define NV40_FP_OP_IADDR_SHIFT 2
272 #define NV40_FP_OP_IADDR_MASK (0xFF << 2)
273
274 /* SRC1 REP
275 * I have no idea why there are 3 count values here.. but they
276 * have always been filled with the same value in my tests so
277 * far..
278 */
279 #define NV40_FP_OP_REP_COUNT1_SHIFT 2
280 #define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
281 #define NV40_FP_OP_REP_COUNT2_SHIFT 10
282 #define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
283 #define NV40_FP_OP_REP_COUNT3_SHIFT 19
284 #define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
285
286 /* SRC2 REP/IF */
287 #define NV40_FP_OP_END_ID_SHIFT 2
288 #define NV40_FP_OP_END_ID_MASK (0xFF << 2)
289
290 /* high order bits of SRC2 */
291 #define NVFX_FP_OP_INDEX_INPUT (1 << 30)
292 #define NV40_FP_OP_ADDR_INDEX_SHIFT 19
293 #define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
294
295 //== Register selection ==
296 #define NVFX_FP_REG_TYPE_SHIFT 0
297 #define NVFX_FP_REG_TYPE_MASK (3 << 0)
298 # define NVFX_FP_REG_TYPE_TEMP 0
299 # define NVFX_FP_REG_TYPE_INPUT 1
300 # define NVFX_FP_REG_TYPE_CONST 2
301 #define NVFX_FP_REG_SRC_SHIFT 2
302 #define NV30_FP_REG_SRC_MASK (31 << 2)
303 #define NV40_FP_REG_SRC_MASK (63 << 2)
304 #define NVFX_FP_REG_SRC_HALF (1 << 8)
305 #define NVFX_FP_REG_SWZ_ALL_SHIFT 9
306 #define NVFX_FP_REG_SWZ_ALL_MASK (255 << 9)
307 #define NVFX_FP_REG_SWZ_X_SHIFT 9
308 #define NVFX_FP_REG_SWZ_X_MASK (3 << 9)
309 #define NVFX_FP_REG_SWZ_Y_SHIFT 11
310 #define NVFX_FP_REG_SWZ_Y_MASK (3 << 11)
311 #define NVFX_FP_REG_SWZ_Z_SHIFT 13
312 #define NVFX_FP_REG_SWZ_Z_MASK (3 << 13)
313 #define NVFX_FP_REG_SWZ_W_SHIFT 15
314 #define NVFX_FP_REG_SWZ_W_MASK (3 << 15)
315 # define NVFX_FP_SWIZZLE_X 0
316 # define NVFX_FP_SWIZZLE_Y 1
317 # define NVFX_FP_SWIZZLE_Z 2
318 # define NVFX_FP_SWIZZLE_W 3
319 #define NVFX_FP_REG_NEGATE (1 << 17)
320
321 #define NVFXSR_NONE 0
322 #define NVFXSR_OUTPUT 1
323 #define NVFXSR_INPUT 2
324 #define NVFXSR_TEMP 3
325 #define NVFXSR_CONST 4
326
327 #define NVFX_COND_FL 0
328 #define NVFX_COND_LT 1
329 #define NVFX_COND_EQ 2
330 #define NVFX_COND_LE 3
331 #define NVFX_COND_GT 4
332 #define NVFX_COND_NE 5
333 #define NVFX_COND_GE 6
334 #define NVFX_COND_TR 7
335
336 /* Yes, this are ordered differently... */
337
338 #define NVFX_VP_MASK_X 8
339 #define NVFX_VP_MASK_Y 4
340 #define NVFX_VP_MASK_Z 2
341 #define NVFX_VP_MASK_W 1
342 #define NVFX_VP_MASK_ALL 0xf
343
344 #define NVFX_FP_MASK_X 1
345 #define NVFX_FP_MASK_Y 2
346 #define NVFX_FP_MASK_Z 4
347 #define NVFX_FP_MASK_W 8
348 #define NVFX_FP_MASK_ALL 0xf
349
350 #define NVFX_SWZ_X 0
351 #define NVFX_SWZ_Y 1
352 #define NVFX_SWZ_Z 2
353 #define NVFX_SWZ_W 3
354
355 #define swz(s,x,y,z,w) nvfx_sr_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)
356 #define neg(s) nvfx_sr_neg((s))
357 #define abs(s) nvfx_sr_abs((s))
358 #define scale(s,v) nvfx_sr_scale((s), NVFX_FP_OP_DST_SCALE_##v)
359
360 struct nvfx_sreg {
361 int type;
362 int index;
363
364 int dst_scale;
365
366 int negate;
367 int abs;
368 int swz[4];
369
370 int cc_update;
371 int cc_update_reg;
372 int cc_test;
373 int cc_test_reg;
374 int cc_swz[4];
375 };
376
377 static INLINE struct nvfx_sreg
378 nvfx_sr(int type, int index)
379 {
380 struct nvfx_sreg temp = {
381 .type = type,
382 .index = index,
383 .dst_scale = 0,
384 .abs = 0,
385 .negate = 0,
386 .swz = { 0, 1, 2, 3 },
387 .cc_update = 0,
388 .cc_update_reg = 0,
389 .cc_test = NVFX_COND_TR,
390 .cc_test_reg = 0,
391 .cc_swz = { 0, 1, 2, 3 },
392 };
393 return temp;
394 }
395
396 static INLINE struct nvfx_sreg
397 nvfx_sr_swz(struct nvfx_sreg src, int x, int y, int z, int w)
398 {
399 struct nvfx_sreg dst = src;
400
401 dst.swz[NVFX_SWZ_X] = src.swz[x];
402 dst.swz[NVFX_SWZ_Y] = src.swz[y];
403 dst.swz[NVFX_SWZ_Z] = src.swz[z];
404 dst.swz[NVFX_SWZ_W] = src.swz[w];
405 return dst;
406 }
407
408 static INLINE struct nvfx_sreg
409 nvfx_sr_neg(struct nvfx_sreg src)
410 {
411 src.negate = !src.negate;
412 return src;
413 }
414
415 static INLINE struct nvfx_sreg
416 nvfx_sr_abs(struct nvfx_sreg src)
417 {
418 src.abs = 1;
419 return src;
420 }
421
422 static INLINE struct nvfx_sreg
423 nvfx_sr_scale(struct nvfx_sreg src, int scale)
424 {
425 src.dst_scale = scale;
426 return src;
427 }
428
429 #endif