1
#ifndef __NVFX_SHADER_H__
2
#define __NVFX_SHADER_H__
6
#include "pipe/p_compiler.h"
8
#define NVFX_SWZ_IDENTITY ((3 << 6) | (2 << 4) | (1 << 2) | (0 << 0))
10
/* this will resolve to either the NV30 or the NV40 version
11
* depending on the current hardware */
12
/* unusual, but very fast and compact method */
13
#define NVFX_VP(c) ((NV30_VP_##c) + (vpc->is_nv4x & ((NV40_VP_##c) - (NV30_VP_##c))))
15
#define NVFX_VP_INST_SLOT_VEC 0
16
#define NVFX_VP_INST_SLOT_SCA 1
18
#define NVFX_VP_INST_IN_POS 0 /* These seem to match the bindings specified in */
19
#define NVFX_VP_INST_IN_WEIGHT 1 /* the ARB_v_p spec (2.14.3.1) */
20
#define NVFX_VP_INST_IN_NORMAL 2
21
#define NVFX_VP_INST_IN_COL0 3 /* Should probably confirm them all though */
22
#define NVFX_VP_INST_IN_COL1 4
23
#define NVFX_VP_INST_IN_FOGC 5
24
#define NVFX_VP_INST_IN_TC0 8
25
#define NVFX_VP_INST_IN_TC(n) (8+n)
27
#define NVFX_VP_INST_SCA_OP_NOP 0x00
28
#define NVFX_VP_INST_SCA_OP_MOV 0x01
29
#define NVFX_VP_INST_SCA_OP_RCP 0x02
30
#define NVFX_VP_INST_SCA_OP_RCC 0x03
31
#define NVFX_VP_INST_SCA_OP_RSQ 0x04
32
#define NVFX_VP_INST_SCA_OP_EXP 0x05
33
#define NVFX_VP_INST_SCA_OP_LOG 0x06
34
#define NVFX_VP_INST_SCA_OP_LIT 0x07
35
#define NVFX_VP_INST_SCA_OP_BRA 0x09
36
#define NVFX_VP_INST_SCA_OP_CAL 0x0B
37
#define NVFX_VP_INST_SCA_OP_RET 0x0C
38
#define NVFX_VP_INST_SCA_OP_LG2 0x0D
39
#define NVFX_VP_INST_SCA_OP_EX2 0x0E
40
#define NVFX_VP_INST_SCA_OP_SIN 0x0F
41
#define NVFX_VP_INST_SCA_OP_COS 0x10
43
#define NV40_VP_INST_SCA_OP_PUSHA 0x13
44
#define NV40_VP_INST_SCA_OP_POPA 0x14
46
#define NVFX_VP_INST_VEC_OP_NOP 0x00
47
#define NVFX_VP_INST_VEC_OP_MOV 0x01
48
#define NVFX_VP_INST_VEC_OP_MUL 0x02
49
#define NVFX_VP_INST_VEC_OP_ADD 0x03
50
#define NVFX_VP_INST_VEC_OP_MAD 0x04
51
#define NVFX_VP_INST_VEC_OP_DP3 0x05
52
#define NVFX_VP_INST_VEC_OP_DPH 0x06
53
#define NVFX_VP_INST_VEC_OP_DP4 0x07
54
#define NVFX_VP_INST_VEC_OP_DST 0x08
55
#define NVFX_VP_INST_VEC_OP_MIN 0x09
56
#define NVFX_VP_INST_VEC_OP_MAX 0x0A
57
#define NVFX_VP_INST_VEC_OP_SLT 0x0B
58
#define NVFX_VP_INST_VEC_OP_SGE 0x0C
59
#define NVFX_VP_INST_VEC_OP_ARL 0x0D
60
#define NVFX_VP_INST_VEC_OP_FRC 0x0E
61
#define NVFX_VP_INST_VEC_OP_FLR 0x0F
62
#define NVFX_VP_INST_VEC_OP_SEQ 0x10
63
#define NVFX_VP_INST_VEC_OP_SFL 0x11
64
#define NVFX_VP_INST_VEC_OP_SGT 0x12
65
#define NVFX_VP_INST_VEC_OP_SLE 0x13
66
#define NVFX_VP_INST_VEC_OP_SNE 0x14
67
#define NVFX_VP_INST_VEC_OP_STR 0x15
68
#define NVFX_VP_INST_VEC_OP_SSG 0x16
69
#define NVFX_VP_INST_VEC_OP_ARR 0x17
70
#define NVFX_VP_INST_VEC_OP_ARA 0x18
72
#define NV40_VP_INST_VEC_OP_TXL 0x19
75
#define NVFX_VP_INST_LAST (1 << 0)
78
* Each fragment program opcode appears to be comprised of 4 32-bit values.
82
* 1-6: destination register
83
* 7: destination register is fp16?? (use for outputs)
84
* 8: set condition code
89
* 13-16: source attribute register number (e.g. COL0)
90
* 17-20: texture unit number
91
* 21: expand value on texture operation (x -> 2x - 1)
92
* 22-23: precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = s0.8 fixed (nv40-only))
97
* 0-17: see common source fields
98
* 18: execute if condition code less
99
* 19: execute if condition code equal
100
* 20: execute if condition code greater
101
* 21-22: condition code swizzle x source component
102
* 23-24: condition code swizzle y source component
103
* 25-26: condition code swizzle z source component
104
* 27-28: condition code swizzle w source component
105
* 29: source 0 absolute
106
* 30: always 0 in renouveau tests
107
* 31: always 0 in renouveau tests
109
* 0-17: see common source fields
110
* 18: source 1 absolute
111
* 19-20: input precision 0 = fp32, 1 = fp16, 2 = s1.10 fixed, 3 = ???
112
* 21-27: always 0 in renouveau tests
113
* 28-30: scale (0 = 1x, 1 = 2x, 2 = 4x, 3 = 8x, 4 = ???, 5, = 1/2, 6 = 1/4, 7 = 1/8)
114
* 31: opcode is branch
116
* 0-17: see common source fields
117
* 18: source 2 absolute
118
* 19-29: address register displacement
119
* 30: use index register
120
* 31: disable perspective-correct interpolation?
122
* Common fields of 0, 1, 2 - SRC
123
* 0-1: source register type (0 = temp, 1 = input, 2 = immediate, 3 = ???)
124
* 2-7: source temp register index
125
* 8: source register is fp16??
126
* 9-10: source swizzle x source component
127
* 11-12: source swizzle y source component
128
* 13-14: source swizzle z source component
129
* 15-16: source swizzle w source component
132
* There appears to be no special difference between result regs and temp regs.
133
* result.color == R0.xyzw
134
* result.depth == R1.z
135
* When the fragprog contains instructions to write depth, NV30_TCL_PRIMITIVE_3D_UNK1D78=0
136
* otherwise it is set to 1.
138
* Constants are inserted directly after the instruction that uses them.
140
* It appears that it's not possible to use two input registers in one
141
* instruction as the input sourcing is done in the instruction dword
142
* and not the source selection dwords. As such instructions such as:
144
* ADD result.color, fragment.color, fragment.texcoord[0];
146
* must be split into two MOV's and then an ADD (nvidia does this) but
147
* I'm not sure why it's not just one MOV and then source the second input
148
* in the ADD instruction..
150
* Negation of the full source is done with NV30_FP_REG_NEGATE, arbitrary
151
* negation requires multiplication with a const.
153
* Arbitrary swizzling is supported with the exception of SWIZZLE_ZERO/SWIZZLE_ONE
154
* The temp/result regs appear to be initialised to (0.0, 0.0, 0.0, 0.0) as SWIZZLE_ZERO
155
* is implemented simply by not writing to the relevant components of the destination.
157
* Conditional execution
160
* Non-native instructions:
163
* SUB - ADD, negate second source
165
* POW - LG2 + MUL + EX2
168
* Loops appear to be fairly expensive on NV40 at least, the proprietary
169
* driver goes to a lot of effort to avoid using the native looping
170
* instructions. If the total number of *executed* instructions between
171
* REP/ENDREP or LOOP/ENDLOOP is <=500, the driver will unroll the loop.
172
* The maximum loop count is 255.
176
//== Opcode / Destination selection ==
177
#define NVFX_FP_OP_PROGRAM_END (1 << 0)
178
#define NVFX_FP_OP_OUT_REG_SHIFT 1
179
#define NV30_FP_OP_OUT_REG_MASK (31 << 1) /* uncertain */
180
#define NV40_FP_OP_OUT_REG_MASK (63 << 1)
181
/* Needs to be set when writing outputs to get expected result.. */
182
#define NVFX_FP_OP_OUT_REG_HALF (1 << 7)
183
#define NVFX_FP_OP_COND_WRITE_ENABLE (1 << 8)
184
#define NVFX_FP_OP_OUTMASK_SHIFT 9
185
#define NVFX_FP_OP_OUTMASK_MASK (0xF << 9)
186
# define NVFX_FP_OP_OUT_X (1<<9)
187
# define NVFX_FP_OP_OUT_Y (1<<10)
188
# define NVFX_FP_OP_OUT_Z (1<<11)
189
# define NVFX_FP_OP_OUT_W (1<<12)
190
/* Uncertain about these, especially the input_src values.. it's possible that
191
* they can be dynamically changed.
193
#define NVFX_FP_OP_INPUT_SRC_SHIFT 13
194
#define NVFX_FP_OP_INPUT_SRC_MASK (15 << 13)
195
# define NVFX_FP_OP_INPUT_SRC_POSITION 0x0
196
# define NVFX_FP_OP_INPUT_SRC_COL0 0x1
197
# define NVFX_FP_OP_INPUT_SRC_COL1 0x2
198
# define NVFX_FP_OP_INPUT_SRC_FOGC 0x3
199
# define NVFX_FP_OP_INPUT_SRC_TC0 0x4
200
# define NVFX_FP_OP_INPUT_SRC_TC(n) (0x4 + n)
201
# define NV40_FP_OP_INPUT_SRC_FACING 0xE
202
#define NVFX_FP_OP_TEX_UNIT_SHIFT 17
203
#define NVFX_FP_OP_TEX_UNIT_MASK (0xF << 17) /* guess */
204
#define NVFX_FP_OP_PRECISION_SHIFT 22
205
#define NVFX_FP_OP_PRECISION_MASK (3 << 22)
206
# define NVFX_FP_PRECISION_FP32 0
207
# define NVFX_FP_PRECISION_FP16 1
208
# define NVFX_FP_PRECISION_FX12 2
209
#define NVFX_FP_OP_OPCODE_SHIFT 24
210
#define NVFX_FP_OP_OPCODE_MASK (0x3F << 24)
211
/* NV30/NV40 fragment program opcodes */
212
#define NVFX_FP_OP_OPCODE_NOP 0x00
213
#define NVFX_FP_OP_OPCODE_MOV 0x01
214
#define NVFX_FP_OP_OPCODE_MUL 0x02
215
#define NVFX_FP_OP_OPCODE_ADD 0x03
216
#define NVFX_FP_OP_OPCODE_MAD 0x04
217
#define NVFX_FP_OP_OPCODE_DP3 0x05
218
#define NVFX_FP_OP_OPCODE_DP4 0x06
219
#define NVFX_FP_OP_OPCODE_DST 0x07
220
#define NVFX_FP_OP_OPCODE_MIN 0x08
221
#define NVFX_FP_OP_OPCODE_MAX 0x09
222
#define NVFX_FP_OP_OPCODE_SLT 0x0A
223
#define NVFX_FP_OP_OPCODE_SGE 0x0B
224
#define NVFX_FP_OP_OPCODE_SLE 0x0C
225
#define NVFX_FP_OP_OPCODE_SGT 0x0D
226
#define NVFX_FP_OP_OPCODE_SNE 0x0E
227
#define NVFX_FP_OP_OPCODE_SEQ 0x0F
228
#define NVFX_FP_OP_OPCODE_FRC 0x10
229
#define NVFX_FP_OP_OPCODE_FLR 0x11
230
#define NVFX_FP_OP_OPCODE_KIL 0x12
231
#define NVFX_FP_OP_OPCODE_PK4B 0x13
232
#define NVFX_FP_OP_OPCODE_UP4B 0x14
233
#define NVFX_FP_OP_OPCODE_DDX 0x15 /* can only write XY */
234
#define NVFX_FP_OP_OPCODE_DDY 0x16 /* can only write XY */
235
#define NVFX_FP_OP_OPCODE_TEX 0x17
236
#define NVFX_FP_OP_OPCODE_TXP 0x18
237
#define NVFX_FP_OP_OPCODE_TXD 0x19
238
#define NVFX_FP_OP_OPCODE_RCP 0x1A
239
#define NVFX_FP_OP_OPCODE_EX2 0x1C
240
#define NVFX_FP_OP_OPCODE_LG2 0x1D
241
#define NVFX_FP_OP_OPCODE_STR 0x20
242
#define NVFX_FP_OP_OPCODE_SFL 0x21
243
#define NVFX_FP_OP_OPCODE_COS 0x22
244
#define NVFX_FP_OP_OPCODE_SIN 0x23
245
#define NVFX_FP_OP_OPCODE_PK2H 0x24
246
#define NVFX_FP_OP_OPCODE_UP2H 0x25
247
#define NVFX_FP_OP_OPCODE_PK4UB 0x27
248
#define NVFX_FP_OP_OPCODE_UP4UB 0x28
249
#define NVFX_FP_OP_OPCODE_PK2US 0x29
250
#define NVFX_FP_OP_OPCODE_UP2US 0x2A
251
#define NVFX_FP_OP_OPCODE_DP2A 0x2E
252
#define NVFX_FP_OP_OPCODE_TXB 0x31
253
#define NVFX_FP_OP_OPCODE_DIV 0x3A
255
/* NV30 only fragment program opcodes */
256
#define NVFX_FP_OP_OPCODE_RSQ_NV30 0x1B
257
#define NVFX_FP_OP_OPCODE_LIT_NV30 0x1E
258
#define NVFX_FP_OP_OPCODE_LRP_NV30 0x1F
259
#define NVFX_FP_OP_OPCODE_POW_NV30 0x26
260
#define NVFX_FP_OP_OPCODE_RFL_NV30 0x36
262
/* NV40 only fragment program opcodes */
263
#define NVFX_FP_OP_OPCODE_TXL_NV40 0x2F
264
#define NVFX_FP_OP_OPCODE_LITEX2_NV40 0x3C
266
/* The use of these instructions appears to be indicated by bit 31 of DWORD 2.*/
267
#define NV40_FP_OP_BRA_OPCODE_BRK 0x0
268
#define NV40_FP_OP_BRA_OPCODE_CAL 0x1
269
#define NV40_FP_OP_BRA_OPCODE_IF 0x2
270
#define NV40_FP_OP_BRA_OPCODE_LOOP 0x3
271
#define NV40_FP_OP_BRA_OPCODE_REP 0x4
272
#define NV40_FP_OP_BRA_OPCODE_RET 0x5
274
#define NV40_FP_OP_OUT_NONE (1 << 30)
275
#define NVFX_FP_OP_OUT_SAT (1 << 31)
277
/* high order bits of SRC0 */
278
#define NVFX_FP_OP_SRC0_ABS (1 << 29)
279
#define NVFX_FP_OP_COND_SWZ_W_SHIFT 27
280
#define NVFX_FP_OP_COND_SWZ_W_MASK (3 << 27)
281
#define NVFX_FP_OP_COND_SWZ_Z_SHIFT 25
282
#define NVFX_FP_OP_COND_SWZ_Z_MASK (3 << 25)
283
#define NVFX_FP_OP_COND_SWZ_Y_SHIFT 23
284
#define NVFX_FP_OP_COND_SWZ_Y_MASK (3 << 23)
285
#define NVFX_FP_OP_COND_SWZ_X_SHIFT 21
286
#define NVFX_FP_OP_COND_SWZ_X_MASK (3 << 21)
287
#define NVFX_FP_OP_COND_SWZ_ALL_SHIFT 21
288
#define NVFX_FP_OP_COND_SWZ_ALL_MASK (0xFF << 21)
289
#define NVFX_FP_OP_COND_SHIFT 18
290
#define NVFX_FP_OP_COND_MASK (0x07 << 18)
291
# define NVFX_FP_OP_COND_FL 0
292
# define NVFX_FP_OP_COND_LT 1
293
# define NVFX_FP_OP_COND_EQ 2
294
# define NVFX_FP_OP_COND_LE 3
295
# define NVFX_FP_OP_COND_GT 4
296
# define NVFX_FP_OP_COND_NE 5
297
# define NVFX_FP_OP_COND_GE 6
298
# define NVFX_FP_OP_COND_TR 7
300
/* high order bits of SRC1 */
301
#define NV40_FP_OP_OPCODE_IS_BRANCH (1<<31)
302
#define NVFX_FP_OP_DST_SCALE_SHIFT 28
303
#define NVFX_FP_OP_DST_SCALE_MASK (3 << 28)
304
#define NVFX_FP_OP_DST_SCALE_1X 0
305
#define NVFX_FP_OP_DST_SCALE_2X 1
306
#define NVFX_FP_OP_DST_SCALE_4X 2
307
#define NVFX_FP_OP_DST_SCALE_8X 3
308
#define NVFX_FP_OP_DST_SCALE_INV_2X 5
309
#define NVFX_FP_OP_DST_SCALE_INV_4X 6
310
#define NVFX_FP_OP_DST_SCALE_INV_8X 7
311
#define NVFX_FP_OP_SRC1_ABS (1 << 18)
314
#define NV40_FP_OP_LOOP_INCR_SHIFT 19
315
#define NV40_FP_OP_LOOP_INCR_MASK (0xFF << 19)
316
#define NV40_FP_OP_LOOP_INDEX_SHIFT 10
317
#define NV40_FP_OP_LOOP_INDEX_MASK (0xFF << 10)
318
#define NV40_FP_OP_LOOP_COUNT_SHIFT 2
319
#define NV40_FP_OP_LOOP_COUNT_MASK (0xFF << 2)
321
/* SRC1 IF: absolute offset in dwords */
322
#define NV40_FP_OP_ELSE_OFFSET_SHIFT 0
323
#define NV40_FP_OP_ELSE_OFFSET_MASK (0x7FFFFFFF << 0)
326
#define NV40_FP_OP_SUB_OFFSET_SHIFT 0
327
#define NV40_FP_OP_SUB_OFFSET_MASK (0x7FFFFFFF << 0)
330
* I have no idea why there are 3 count values here.. but they
331
* have always been filled with the same value in my tests so
334
#define NV40_FP_OP_REP_COUNT1_SHIFT 2
335
#define NV40_FP_OP_REP_COUNT1_MASK (0xFF << 2)
336
#define NV40_FP_OP_REP_COUNT2_SHIFT 10
337
#define NV40_FP_OP_REP_COUNT2_MASK (0xFF << 10)
338
#define NV40_FP_OP_REP_COUNT3_SHIFT 19
339
#define NV40_FP_OP_REP_COUNT3_MASK (0xFF << 19)
341
/* SRC2 REP/IF: absolute offset in dwords */
342
#define NV40_FP_OP_END_OFFSET_SHIFT 0
343
#define NV40_FP_OP_END_OFFSET_MASK (0x7FFFFFFF << 0)
345
/* high order bits of SRC2 */
346
#define NVFX_FP_OP_INDEX_INPUT (1 << 30)
347
#define NV40_FP_OP_ADDR_INDEX_SHIFT 19
348
#define NV40_FP_OP_ADDR_INDEX_MASK (0xF << 19)
350
//== Register selection ==
351
#define NVFX_FP_REG_TYPE_SHIFT 0
352
#define NVFX_FP_REG_TYPE_MASK (3 << 0)
353
# define NVFX_FP_REG_TYPE_TEMP 0
354
# define NVFX_FP_REG_TYPE_INPUT 1
355
# define NVFX_FP_REG_TYPE_CONST 2
356
#define NVFX_FP_REG_SRC_SHIFT 2
357
#define NV30_FP_REG_SRC_MASK (31 << 2)
358
#define NV40_FP_REG_SRC_MASK (63 << 2)
359
#define NVFX_FP_REG_SRC_HALF (1 << 8)
360
#define NVFX_FP_REG_SWZ_ALL_SHIFT 9
361
#define NVFX_FP_REG_SWZ_ALL_MASK (255 << 9)
362
#define NVFX_FP_REG_SWZ_X_SHIFT 9
363
#define NVFX_FP_REG_SWZ_X_MASK (3 << 9)
364
#define NVFX_FP_REG_SWZ_Y_SHIFT 11
365
#define NVFX_FP_REG_SWZ_Y_MASK (3 << 11)
366
#define NVFX_FP_REG_SWZ_Z_SHIFT 13
367
#define NVFX_FP_REG_SWZ_Z_MASK (3 << 13)
368
#define NVFX_FP_REG_SWZ_W_SHIFT 15
369
#define NVFX_FP_REG_SWZ_W_MASK (3 << 15)
370
# define NVFX_FP_SWIZZLE_X 0
371
# define NVFX_FP_SWIZZLE_Y 1
372
# define NVFX_FP_SWIZZLE_Z 2
373
# define NVFX_FP_SWIZZLE_W 3
374
#define NVFX_FP_REG_NEGATE (1 << 17)
376
#define NVFXSR_NONE 0
377
#define NVFXSR_OUTPUT 1
378
#define NVFXSR_INPUT 2
379
#define NVFXSR_TEMP 3
380
#define NVFXSR_CONST 5
383
#define NVFX_COND_FL 0
384
#define NVFX_COND_LT 1
385
#define NVFX_COND_EQ 2
386
#define NVFX_COND_LE 3
387
#define NVFX_COND_GT 4
388
#define NVFX_COND_NE 5
389
#define NVFX_COND_GE 6
390
#define NVFX_COND_TR 7
392
/* Yes, this are ordered differently... */
394
#define NVFX_VP_MASK_X 8
395
#define NVFX_VP_MASK_Y 4
396
#define NVFX_VP_MASK_Z 2
397
#define NVFX_VP_MASK_W 1
398
#define NVFX_VP_MASK_ALL 0xf
400
#define NVFX_FP_MASK_X 1
401
#define NVFX_FP_MASK_Y 2
402
#define NVFX_FP_MASK_Z 4
403
#define NVFX_FP_MASK_W 8
404
#define NVFX_FP_MASK_ALL 0xf
411
#define swz(s,x,y,z,w) nvfx_src_swz((s), NVFX_SWZ_##x, NVFX_SWZ_##y, NVFX_SWZ_##z, NVFX_SWZ_##w)
412
#define neg(s) nvfx_src_neg((s))
413
#define abs(s) nvfx_src_abs((s))
423
uint8_t indirect : 1;
424
uint8_t indirect_reg : 1;
425
uint8_t indirect_swz : 2;
440
uint8_t cc_update : 1;
441
uint8_t cc_update_reg : 1;
443
uint8_t cc_test_reg : 1;
446
struct nvfx_src src[3];
449
static inline struct nvfx_insn
450
nvfx_insn(bool sat, unsigned op, int unit, struct nvfx_reg dst, unsigned mask, struct nvfx_src s0, struct nvfx_src s1, struct nvfx_src s2)
452
struct nvfx_insn insn = {
460
.cc_test = NVFX_COND_TR,
462
.cc_swz = { 0, 1, 2, 3 },
469
static inline struct nvfx_reg
470
nvfx_reg(int type, int index)
472
struct nvfx_reg temp = {
479
static inline struct nvfx_src
480
nvfx_src(struct nvfx_reg reg)
482
struct nvfx_src temp = {
486
.swz = { 0, 1, 2, 3 },
492
static inline struct nvfx_src
493
nvfx_src_swz(struct nvfx_src src, int x, int y, int z, int w)
495
struct nvfx_src dst = src;
497
dst.swz[NVFX_SWZ_X] = src.swz[x];
498
dst.swz[NVFX_SWZ_Y] = src.swz[y];
499
dst.swz[NVFX_SWZ_Z] = src.swz[z];
500
dst.swz[NVFX_SWZ_W] = src.swz[w];
504
static inline struct nvfx_src
505
nvfx_src_neg(struct nvfx_src src)
507
src.negate = !src.negate;
511
static inline struct nvfx_src
512
nvfx_src_abs(struct nvfx_src src)
518
struct nvfx_relocation {
523
struct nv30_fragprog;
524
struct nv30_vertprog;
526
//XXX: needed to make it build, clean this up!
528
_nvfx_fragprog_translate(uint16_t oclass, struct nv30_fragprog *fp);
531
_nvfx_vertprog_translate(uint16_t oclass, struct nv30_vertprog *vp);