1 #include "nouveau_shader.h"
2 #include "nouveau_msg.h"
3 #include "nv40_shader.h"
5 /*****************************************************************************
9 NV40VPSupportsOpcode(nvsFunc
* shader
, nvsOpcode op
)
11 if (shader
->GetOPTXFromSOP(op
, NULL
))
17 NV40VPSetOpcode(nvsFunc
*shader
, unsigned int opcode
, int slot
)
20 shader
->inst
[1] &= ~NV40_VP_INST_SCA_OPCODE_MASK
;
21 shader
->inst
[1] |= (opcode
<< NV40_VP_INST_SCA_OPCODE_SHIFT
);
23 shader
->inst
[1] &= ~NV40_VP_INST_VEC_OPCODE_MASK
;
24 shader
->inst
[1] |= (opcode
<< NV40_VP_INST_VEC_OPCODE_SHIFT
);
29 NV40VPSetCCUpdate(nvsFunc
*shader
)
31 shader
->inst
[0] |= NV40_VP_INST_COND_UPDATE_ENABLE
;
35 NV40VPSetCondition(nvsFunc
*shader
, int on
, nvsCond cond
, int reg
,
40 if (on
) shader
->inst
[0] |= NV40_VP_INST_COND_TEST_ENABLE
;
41 else shader
->inst
[0] &= ~NV40_VP_INST_COND_TEST_ENABLE
;
42 if (reg
) shader
->inst
[0] |= NV40_VP_INST_COND_REG_SELECT_1
;
43 else shader
->inst
[0] &= ~NV40_VP_INST_COND_REG_SELECT_1
;
46 case NVS_COND_TR
: hwcond
= NV40_VP_INST_COND_TR
; break;
47 case NVS_COND_FL
: hwcond
= NV40_VP_INST_COND_FL
; break;
48 case NVS_COND_LT
: hwcond
= NV40_VP_INST_COND_LT
; break;
49 case NVS_COND_GT
: hwcond
= NV40_VP_INST_COND_GT
; break;
50 case NVS_COND_NE
: hwcond
= NV40_VP_INST_COND_NE
; break;
51 case NVS_COND_EQ
: hwcond
= NV40_VP_INST_COND_EQ
; break;
52 case NVS_COND_GE
: hwcond
= NV40_VP_INST_COND_GE
; break;
53 case NVS_COND_LE
: hwcond
= NV40_VP_INST_COND_LE
; break;
55 WARN_ONCE("unknown vp cond %d\n", cond
);
56 hwcond
= NV40_VP_INST_COND_TR
;
59 shader
->inst
[0] &= ~NV40_VP_INST_COND_MASK
;
60 shader
->inst
[0] |= (hwcond
<< NV40_VP_INST_COND_SHIFT
);
62 shader
->inst
[0] &= ~NV40_VP_INST_COND_SWZ_ALL_MASK
;
63 shader
->inst
[0] |= (swizzle
[NVS_SWZ_X
] << NV40_VP_INST_COND_SWZ_X_SHIFT
);
64 shader
->inst
[0] |= (swizzle
[NVS_SWZ_Y
] << NV40_VP_INST_COND_SWZ_Y_SHIFT
);
65 shader
->inst
[0] |= (swizzle
[NVS_SWZ_Z
] << NV40_VP_INST_COND_SWZ_Z_SHIFT
);
66 shader
->inst
[0] |= (swizzle
[NVS_SWZ_W
] << NV40_VP_INST_COND_SWZ_W_SHIFT
);
69 /* these just exist here until nouveau_reg.h has them. */
70 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0 (1<<0)
71 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1 (1<<1)
72 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0 (1<<2)
73 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1 (1<<3)
74 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC (1<<4)
75 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ (1<<5)
76 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0 (1<<6)
77 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1 (1<<7)
78 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2 (1<<8)
79 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3 (1<<9)
80 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4 (1<<10)
81 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5 (1<<11)
82 #define NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0 (1<<14)
85 NV40VPTranslateResultReg(nvsFunc
*shader
, nvsFixedReg result
,
86 unsigned int *mask_ret
)
88 unsigned int *out_reg
= &shader
->card_priv
->NV30VP
.vp_out_reg
;
89 unsigned int *clip_en
= &shader
->card_priv
->NV30VP
.clip_enables
;
95 /* out_reg POS implied */
96 return NV40_VP_INST_DEST_POS
;
98 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL0
;
99 return NV40_VP_INST_DEST_COL0
;
101 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_COL1
;
102 return NV40_VP_INST_DEST_COL1
;
104 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC0
;
105 return NV40_VP_INST_DEST_BFC0
;
107 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_BFC1
;
108 return NV40_VP_INST_DEST_BFC1
;
109 case NVS_FR_FOGCOORD
:
110 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_FOGC
;
112 return NV40_VP_INST_DEST_FOGC
;
114 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP0
;
115 (*clip_en
) |= 0x00000002;
117 return NV40_VP_INST_DEST_FOGC
;
119 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP1
;
120 (*clip_en
) |= 0x00000020;
122 return NV40_VP_INST_DEST_FOGC
;
124 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP2
;
125 (*clip_en
) |= 0x00000200;
127 return NV40_VP_INST_DEST_FOGC
;
129 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_PSZ
;
131 return NV40_VP_INST_DEST_PSZ
;
133 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP3
;
134 (*clip_en
) |= 0x00002000;
136 return NV40_VP_INST_DEST_PSZ
;
138 (*clip_en
) |= 0x00020000;
139 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP4
;
141 return NV40_VP_INST_DEST_PSZ
;
143 (*clip_en
) |= 0x00200000;
144 (*out_reg
) |= NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_CLP5
;
146 return NV40_VP_INST_DEST_PSZ
;
147 case NVS_FR_TEXCOORD0
:
148 case NVS_FR_TEXCOORD1
:
149 case NVS_FR_TEXCOORD2
:
150 case NVS_FR_TEXCOORD3
:
151 case NVS_FR_TEXCOORD4
:
152 case NVS_FR_TEXCOORD5
:
153 case NVS_FR_TEXCOORD6
:
154 case NVS_FR_TEXCOORD7
:
156 int unit
= result
- NVS_FR_TEXCOORD0
;
157 (*out_reg
) |= (NV30_TCL_PRIMITIVE_3D_VP_OUT_REG_TEX0
<< unit
);
158 return NV40_VP_INST_DEST_TC(unit
);
161 WARN_ONCE("unknown vp output %d\n", result
);
162 return NV40_VP_INST_DEST_POS
;
167 NV40VPSetResult(nvsFunc
*shader
, nvsRegister
* dest
, unsigned int mask
,
170 unsigned int hwmask
= 0;
172 if (mask
& SMASK_X
) hwmask
|= (1 << 3);
173 if (mask
& SMASK_Y
) hwmask
|= (1 << 2);
174 if (mask
& SMASK_Z
) hwmask
|= (1 << 1);
175 if (mask
& SMASK_W
) hwmask
|= (1 << 0);
177 if (dest
->file
== NVS_FILE_RESULT
) {
178 unsigned int valid_mask
;
181 hwidx
= NV40VPTranslateResultReg(shader
, dest
->index
, &valid_mask
);
182 if (hwmask
& ~valid_mask
)
183 WARN_ONCE("writing invalid components of result reg\n");
184 hwmask
&= valid_mask
;
186 shader
->inst
[3] &= ~NV40_VP_INST_DEST_MASK
;
187 shader
->inst
[3] |= (hwidx
<< NV40_VP_INST_DEST_SHIFT
);
189 if (slot
) shader
->inst
[3] |= NV40_VP_INST_SCA_RESULT
;
190 else shader
->inst
[0] |= NV40_VP_INST_VEC_RESULT
;
192 /* NVS_FILE_TEMP || NVS_FILE_ADDRESS */
194 shader
->inst
[3] &= ~NV40_VP_INST_SCA_RESULT
;
195 shader
->inst
[3] &= ~NV40_VP_INST_SCA_DEST_TEMP_MASK
;
196 shader
->inst
[3] |= (dest
->index
<< NV40_VP_INST_SCA_DEST_TEMP_SHIFT
);
198 shader
->inst
[0] &= ~NV40_VP_INST_VEC_RESULT
;
199 shader
->inst
[0] &= ~(NV40_VP_INST_VEC_DEST_TEMP_MASK
| (1<<20));
200 shader
->inst
[0] |= (dest
->index
<< NV40_VP_INST_VEC_DEST_TEMP_SHIFT
);
205 shader
->inst
[3] &= ~NV40_VP_INST_SCA_WRITEMASK_MASK
;
206 shader
->inst
[3] |= (hwmask
<< NV40_VP_INST_SCA_WRITEMASK_SHIFT
);
208 shader
->inst
[3] &= ~NV40_VP_INST_VEC_WRITEMASK_MASK
;
209 shader
->inst
[3] |= (hwmask
<< NV40_VP_INST_VEC_WRITEMASK_SHIFT
);
214 NV40VPInsertSource(nvsFunc
*shader
, unsigned int hw
, int pos
)
218 shader
->inst
[1] &= ~NV40_VP_INST_SRC0H_MASK
;
219 shader
->inst
[2] &= ~NV40_VP_INST_SRC0L_MASK
;
220 shader
->inst
[1] |= ((hw
& NV40_VP_SRC0_HIGH_MASK
) >>
221 NV40_VP_SRC0_HIGH_SHIFT
)
222 << NV40_VP_INST_SRC0H_SHIFT
;
223 shader
->inst
[2] |= (hw
& NV40_VP_SRC0_LOW_MASK
)
224 << NV40_VP_INST_SRC0L_SHIFT
;
227 shader
->inst
[2] &= ~NV40_VP_INST_SRC1_MASK
;
228 shader
->inst
[2] |= hw
229 << NV40_VP_INST_SRC1_SHIFT
;
232 shader
->inst
[2] &= ~NV40_VP_INST_SRC2H_MASK
;
233 shader
->inst
[3] &= ~NV40_VP_INST_SRC2L_MASK
;
234 shader
->inst
[2] |= ((hw
& NV40_VP_SRC2_HIGH_MASK
) >>
235 NV40_VP_SRC2_HIGH_SHIFT
)
236 << NV40_VP_INST_SRC2H_SHIFT
;
237 shader
->inst
[3] |= (hw
& NV40_VP_SRC2_LOW_MASK
)
238 << NV40_VP_INST_SRC2L_SHIFT
;
247 NV40VPSetSource(nvsFunc
*shader
, nvsRegister
* src
, int pos
)
252 case NVS_FILE_ADDRESS
:
254 case NVS_FILE_ATTRIB
:
255 hw
|= (NV40_VP_SRC_REG_TYPE_INPUT
<< NV40_VP_SRC_REG_TYPE_SHIFT
);
257 shader
->inst
[1] &= ~NV40_VP_INST_INPUT_SRC_MASK
;
258 shader
->inst
[1] |= (src
->index
<< NV40_VP_INST_INPUT_SRC_SHIFT
);
259 shader
->card_priv
->NV30VP
.vp_in_reg
|= (1 << src
->index
);
261 shader
->inst
[0] |= NV40_VP_INST_INDEX_INPUT
;
263 shader
->inst
[0] |= NV40_VP_INST_ADDR_REG_SELECT_1
;
265 shader
->inst
[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1
;
266 shader
->inst
[0] &= ~NV40_VP_INST_ADDR_SWZ_SHIFT
;
267 shader
->inst
[0] |= (src
->addr_comp
<< NV40_VP_INST_ADDR_SWZ_SHIFT
);
269 shader
->inst
[0] &= ~NV40_VP_INST_INDEX_INPUT
;
272 hw
|= (NV40_VP_SRC_REG_TYPE_CONST
<< NV40_VP_SRC_REG_TYPE_SHIFT
);
274 shader
->inst
[1] &= ~NV40_VP_INST_CONST_SRC_MASK
;
275 shader
->inst
[1] |= (src
->index
<< NV40_VP_INST_CONST_SRC_SHIFT
);
277 shader
->inst
[3] |= NV40_VP_INST_INDEX_CONST
;
279 shader
->inst
[0] |= NV40_VP_INST_ADDR_REG_SELECT_1
;
281 shader
->inst
[0] &= ~NV40_VP_INST_ADDR_REG_SELECT_1
;
282 shader
->inst
[0] &= ~NV40_VP_INST_ADDR_SWZ_MASK
;
283 shader
->inst
[0] |= (src
->addr_comp
<< NV40_VP_INST_ADDR_SWZ_SHIFT
);
285 shader
->inst
[3] &= ~NV40_VP_INST_INDEX_CONST
;
288 hw
|= (NV40_VP_SRC_REG_TYPE_TEMP
<< NV40_VP_SRC_REG_TYPE_SHIFT
);
289 hw
|= (src
->index
<< NV40_VP_SRC_TEMP_SRC_SHIFT
);
292 fprintf(stderr
, "unknown source file %d\n", src
->file
);
297 if (src
->file
!= NVS_FILE_ADDRESS
) {
299 hw
|= NV40_VP_SRC_NEGATE
;
301 shader
->inst
[0] |= (1 << (21 + pos
));
303 shader
->inst
[0] &= ~(1 << (21 + pos
));
304 hw
|= (src
->swizzle
[0] << NV40_VP_SRC_SWZ_X_SHIFT
);
305 hw
|= (src
->swizzle
[1] << NV40_VP_SRC_SWZ_Y_SHIFT
);
306 hw
|= (src
->swizzle
[2] << NV40_VP_SRC_SWZ_Z_SHIFT
);
307 hw
|= (src
->swizzle
[3] << NV40_VP_SRC_SWZ_W_SHIFT
);
309 NV40VPInsertSource(shader
, hw
, pos
);
314 NV40VPSetBranchTarget(nvsFunc
*shader
, int addr
)
316 shader
->inst
[2] &= ~NV40_VP_INST_IADDRH_MASK
;
317 shader
->inst
[2] |= ((addr
& 0xf8) >> 3) << NV40_VP_INST_IADDRH_SHIFT
;
318 shader
->inst
[3] &= ~NV40_VP_INST_IADDRL_MASK
;
319 shader
->inst
[3] |= ((addr
& 0x07) << NV40_VP_INST_IADDRL_SHIFT
);
323 NV40VPInitInstruction(nvsFunc
*shader
)
325 unsigned int hwsrc
= 0;
327 shader
->inst
[0] = /*NV40_VP_INST_VEC_RESULT | */
328 NV40_VP_INST_VEC_DEST_TEMP_MASK
| (1<<20);
331 shader
->inst
[3] = NV40_VP_INST_SCA_RESULT
|
332 NV40_VP_INST_SCA_DEST_TEMP_MASK
|
333 NV40_VP_INST_DEST_MASK
;
335 hwsrc
= (NV40_VP_SRC_REG_TYPE_INPUT
<< NV40_VP_SRC_REG_TYPE_SHIFT
) |
336 (NVS_SWZ_X
<< NV40_VP_SRC_SWZ_X_SHIFT
) |
337 (NVS_SWZ_Y
<< NV40_VP_SRC_SWZ_Y_SHIFT
) |
338 (NVS_SWZ_Z
<< NV40_VP_SRC_SWZ_Z_SHIFT
) |
339 (NVS_SWZ_W
<< NV40_VP_SRC_SWZ_W_SHIFT
);
340 NV40VPInsertSource(shader
, hwsrc
, 0);
341 NV40VPInsertSource(shader
, hwsrc
, 1);
342 NV40VPInsertSource(shader
, hwsrc
, 2);
346 NV40VPSetLastInst(nvsFunc
*shader
)
348 shader
->inst
[3] |= 1;
351 /*****************************************************************************
352 * Disassembly routines
355 NV40VPHasMergedInst(nvsFunc
* shader
)
357 if (shader
->GetOpcodeHW(shader
, 0) != NV40_VP_INST_OP_NOP
&&
358 shader
->GetOpcodeHW(shader
, 1) != NV40_VP_INST_OP_NOP
)
364 NV40VPGetOpcodeHW(nvsFunc
* shader
, int slot
)
369 op
= (shader
->inst
[1] & NV40_VP_INST_SCA_OPCODE_MASK
)
370 >> NV40_VP_INST_SCA_OPCODE_SHIFT
;
372 op
= (shader
->inst
[1] & NV40_VP_INST_VEC_OPCODE_MASK
)
373 >> NV40_VP_INST_VEC_OPCODE_SHIFT
;
379 NV40VPGetDestFile(nvsFunc
* shader
, int merged
)
383 op
= shader
->GetOpcode(shader
, merged
);
389 return NVS_FILE_ADDRESS
;
391 if (shader
->GetOpcodeSlot(shader
, merged
)) {
392 if (shader
->inst
[3] & NV40_VP_INST_SCA_RESULT
)
393 return NVS_FILE_RESULT
;
396 if (shader
->inst
[0] & NV40_VP_INST_VEC_RESULT
)
397 return NVS_FILE_RESULT
;
399 return NVS_FILE_TEMP
;
405 NV40VPGetDestID(nvsFunc
* shader
, int merged
)
409 switch (shader
->GetDestFile(shader
, merged
)) {
410 case NVS_FILE_RESULT
:
411 id
= ((shader
->inst
[3] & NV40_VP_INST_DEST_MASK
)
412 >> NV40_VP_INST_DEST_SHIFT
);
414 case NV40_VP_INST_DEST_POS
: return NVS_FR_POSITION
;
415 case NV40_VP_INST_DEST_COL0
: return NVS_FR_COL0
;
416 case NV40_VP_INST_DEST_COL1
: return NVS_FR_COL1
;
417 case NV40_VP_INST_DEST_BFC0
: return NVS_FR_BFC0
;
418 case NV40_VP_INST_DEST_BFC1
: return NVS_FR_BFC1
;
419 case NV40_VP_INST_DEST_FOGC
: {
420 int mask
= shader
->GetDestMask(shader
, merged
);
422 case SMASK_X
: return NVS_FR_FOGCOORD
;
423 case SMASK_Y
: return NVS_FR_CLIP0
;
424 case SMASK_Z
: return NVS_FR_CLIP1
;
425 case SMASK_W
: return NVS_FR_CLIP2
;
427 printf("more than 1 mask component set in FOGC writemask!\n");
428 return NVS_FR_UNKNOWN
;
431 case NV40_VP_INST_DEST_PSZ
:
433 int mask
= shader
->GetDestMask(shader
, merged
);
435 case SMASK_X
: return NVS_FR_POINTSZ
;
436 case SMASK_Y
: return NVS_FR_CLIP3
;
437 case SMASK_Z
: return NVS_FR_CLIP4
;
438 case SMASK_W
: return NVS_FR_CLIP5
;
440 printf("more than 1 mask component set in PSZ writemask!\n");
441 return NVS_FR_UNKNOWN
;
444 case NV40_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0
;
445 case NV40_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1
;
446 case NV40_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2
;
447 case NV40_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3
;
448 case NV40_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4
;
449 case NV40_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5
;
450 case NV40_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6
;
451 case NV40_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7
;
455 case NVS_FILE_ADDRESS
:
456 /* Instructions that write address regs are encoded as if
457 * they would write temps.
460 if (shader
->GetOpcodeSlot(shader
, merged
))
461 id
= ((shader
->inst
[3] & NV40_VP_INST_SCA_DEST_TEMP_MASK
)
462 >> NV40_VP_INST_SCA_DEST_TEMP_SHIFT
);
464 id
= ((shader
->inst
[0] & NV40_VP_INST_VEC_DEST_TEMP_MASK
)
465 >> NV40_VP_INST_VEC_DEST_TEMP_SHIFT
);
473 NV40VPGetDestMask(nvsFunc
* shader
, int merged
)
475 unsigned int mask
= 0;
477 if (shader
->GetOpcodeSlot(shader
, merged
)) {
478 if (shader
->inst
[3] & NV40_VP_INST_SCA_WRITEMASK_X
) mask
|= SMASK_X
;
479 if (shader
->inst
[3] & NV40_VP_INST_SCA_WRITEMASK_Y
) mask
|= SMASK_Y
;
480 if (shader
->inst
[3] & NV40_VP_INST_SCA_WRITEMASK_Z
) mask
|= SMASK_Z
;
481 if (shader
->inst
[3] & NV40_VP_INST_SCA_WRITEMASK_W
) mask
|= SMASK_W
;
483 if (shader
->inst
[3] & NV40_VP_INST_VEC_WRITEMASK_X
) mask
|= SMASK_X
;
484 if (shader
->inst
[3] & NV40_VP_INST_VEC_WRITEMASK_Y
) mask
|= SMASK_Y
;
485 if (shader
->inst
[3] & NV40_VP_INST_VEC_WRITEMASK_Z
) mask
|= SMASK_Z
;
486 if (shader
->inst
[3] & NV40_VP_INST_VEC_WRITEMASK_W
) mask
|= SMASK_W
;
493 NV40VPGetSourceHW(nvsFunc
* shader
, int merged
, int pos
)
495 struct _op_xlat
*opr
;
498 opr
= shader
->GetOPTXRec(shader
, merged
);
502 switch (opr
->srcpos
[pos
]) {
504 src
= ((shader
->inst
[1] & NV40_VP_INST_SRC0H_MASK
)
505 >> NV40_VP_INST_SRC0H_SHIFT
)
506 << NV40_VP_SRC0_HIGH_SHIFT
;
507 src
|= ((shader
->inst
[2] & NV40_VP_INST_SRC0L_MASK
)
508 >> NV40_VP_INST_SRC0L_SHIFT
);
511 src
= ((shader
->inst
[2] & NV40_VP_INST_SRC1_MASK
)
512 >> NV40_VP_INST_SRC1_SHIFT
);
515 src
= ((shader
->inst
[2] & NV40_VP_INST_SRC2H_MASK
)
516 >> NV40_VP_INST_SRC2H_SHIFT
)
517 << NV40_VP_SRC2_HIGH_SHIFT
;
518 src
|= ((shader
->inst
[3] & NV40_VP_INST_SRC2L_MASK
)
519 >> NV40_VP_INST_SRC2L_SHIFT
);
529 NV40VPGetSourceFile(nvsFunc
* shader
, int merged
, int pos
)
532 struct _op_xlat
*opr
;
535 opr
= shader
->GetOPTXRec(shader
, merged
);
536 if (!opr
|| opr
->srcpos
[pos
] == -1)
539 switch (opr
->srcpos
[pos
]) {
540 case SPOS_ADDRESS
: return NVS_FILE_ADDRESS
;
542 src
= shader
->GetSourceHW(shader
, merged
, pos
);
543 file
= (src
& NV40_VP_SRC_REG_TYPE_MASK
) >> NV40_VP_SRC_REG_TYPE_SHIFT
;
546 case NV40_VP_SRC_REG_TYPE_TEMP
: return NVS_FILE_TEMP
;
547 case NV40_VP_SRC_REG_TYPE_INPUT
: return NVS_FILE_ATTRIB
;
548 case NV40_VP_SRC_REG_TYPE_CONST
: return NVS_FILE_CONST
;
550 return NVS_FILE_UNKNOWN
;
556 NV40VPGetSourceID(nvsFunc
* shader
, int merged
, int pos
)
558 switch (shader
->GetSourceFile(shader
, merged
, pos
)) {
559 case NVS_FILE_ATTRIB
:
560 switch ((shader
->inst
[1] & NV40_VP_INST_INPUT_SRC_MASK
)
561 >> NV40_VP_INST_INPUT_SRC_SHIFT
) {
562 case NV40_VP_INST_IN_POS
: return NVS_FR_POSITION
;
563 case NV40_VP_INST_IN_WEIGHT
: return NVS_FR_WEIGHT
;
564 case NV40_VP_INST_IN_NORMAL
: return NVS_FR_NORMAL
;
565 case NV40_VP_INST_IN_COL0
: return NVS_FR_COL0
;
566 case NV40_VP_INST_IN_COL1
: return NVS_FR_COL1
;
567 case NV40_VP_INST_IN_FOGC
: return NVS_FR_FOGCOORD
;
568 case NV40_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0
;
569 case NV40_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1
;
570 case NV40_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2
;
571 case NV40_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3
;
572 case NV40_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4
;
573 case NV40_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5
;
574 case NV40_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6
;
575 case NV40_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7
;
581 return ((shader
->inst
[1] & NV40_VP_INST_CONST_SRC_MASK
)
582 >> NV40_VP_INST_CONST_SRC_SHIFT
);
587 src
= shader
->GetSourceHW(shader
, merged
, pos
);
588 return ((src
& NV40_VP_SRC_TEMP_SRC_MASK
) >>
589 NV40_VP_SRC_TEMP_SRC_SHIFT
);
597 NV40VPGetSourceNegate(nvsFunc
* shader
, int merged
, int pos
)
601 src
= shader
->GetSourceHW(shader
, merged
, pos
);
605 return ((src
& NV40_VP_SRC_NEGATE
) ? 1 : 0);
609 NV40VPGetSourceSwizzle(nvsFunc
* shader
, int merged
, int pos
, nvsSwzComp
*swz
)
614 src
= shader
->GetSourceHW(shader
, merged
, pos
);
615 swzbits
= (src
& NV40_VP_SRC_SWZ_ALL_MASK
) >> NV40_VP_SRC_SWZ_ALL_SHIFT
;
616 NV20VPTXSwizzle(swzbits
, swz
);
620 NV40VPGetSourceIndexed(nvsFunc
* shader
, int merged
, int pos
)
622 switch (shader
->GetSourceFile(shader
, merged
, pos
)) {
623 case NVS_FILE_ATTRIB
:
624 return ((shader
->inst
[0] & NV40_VP_INST_INDEX_INPUT
) ? 1 : 0);
626 return ((shader
->inst
[3] & NV40_VP_INST_INDEX_CONST
) ? 1 : 0);
633 NV40VPGetAddressRegSwizzle(nvsFunc
* shader
)
637 swz
= NV20VP_TX_SWIZZLE
[(shader
->inst
[0] & NV40_VP_INST_ADDR_SWZ_MASK
)
638 >> NV40_VP_INST_ADDR_SWZ_SHIFT
];
643 NV40VPSupportsConditional(nvsFunc
* shader
)
645 /*FIXME: Is this true of all ops? */
650 NV40VPGetConditionUpdate(nvsFunc
* shader
)
652 return ((shader
->inst
[0] & NV40_VP_INST_COND_UPDATE_ENABLE
) ? 1 : 0);
656 NV40VPGetConditionTest(nvsFunc
* shader
)
660 /* The condition test is unconditionally enabled on some
661 * instructions. ie: the condition test bit does *NOT* have
664 * FIXME: check other relevant ops for this situation.
666 op
= shader
->GetOpcodeHW(shader
, 1);
668 case NV40_VP_INST_OP_BRA
:
671 return ((shader
->inst
[0] & NV40_VP_INST_COND_TEST_ENABLE
) ? 1 : 0);
676 NV40VPGetCondition(nvsFunc
* shader
)
680 cond
= ((shader
->inst
[0] & NV40_VP_INST_COND_MASK
)
681 >> NV40_VP_INST_COND_SHIFT
);
684 case NV40_VP_INST_COND_FL
: return NVS_COND_FL
;
685 case NV40_VP_INST_COND_LT
: return NVS_COND_LT
;
686 case NV40_VP_INST_COND_EQ
: return NVS_COND_EQ
;
687 case NV40_VP_INST_COND_LE
: return NVS_COND_LE
;
688 case NV40_VP_INST_COND_GT
: return NVS_COND_GT
;
689 case NV40_VP_INST_COND_NE
: return NVS_COND_NE
;
690 case NV40_VP_INST_COND_GE
: return NVS_COND_GE
;
691 case NV40_VP_INST_COND_TR
: return NVS_COND_TR
;
693 return NVS_COND_UNKNOWN
;
698 NV40VPGetCondRegSwizzle(nvsFunc
* shader
, nvsSwzComp
*swz
)
702 swzbits
= (shader
->inst
[0] & NV40_VP_INST_COND_SWZ_ALL_MASK
)
703 >> NV40_VP_INST_COND_SWZ_ALL_SHIFT
;
704 NV20VPTXSwizzle(swzbits
, swz
);
708 NV40VPGetCondRegID(nvsFunc
* shader
)
710 return ((shader
->inst
[0] & NV40_VP_INST_COND_REG_SELECT_1
) ? 1 : 0);
714 NV40VPGetBranch(nvsFunc
* shader
)
718 addr
= ((shader
->inst
[2] & NV40_VP_INST_IADDRH_MASK
)
719 >> NV40_VP_INST_IADDRH_SHIFT
) << 3;
720 addr
|= ((shader
->inst
[3] & NV40_VP_INST_IADDRL_MASK
)
721 >> NV40_VP_INST_IADDRL_SHIFT
);
726 NV40VPInitShaderFuncs(nvsFunc
* shader
)
728 /* Inherit NV30 VP code, we share some of it */
729 NV30VPInitShaderFuncs(shader
);
732 shader
->MaxInst
= 4096;
733 shader
->MaxAttrib
= 16;
734 shader
->MaxTemp
= 32;
735 shader
->MaxAddress
= 2;
736 shader
->MaxConst
= 256;
737 shader
->caps
= SCAP_SRC_ABS
;
739 /* Add extra opcodes for NV40+ */
740 // MOD_OPCODE(NVVP_TX_VOP, NV40_VP_INST_OP_TXWHAT, NVS_OP_TEX , 0, 4, -1);
741 MOD_OPCODE(NVVP_TX_SOP
, NV40_VP_INST_OP_PUSHA
, NVS_OP_PUSHA
, 3, -1, -1);
742 MOD_OPCODE(NVVP_TX_SOP
, NV40_VP_INST_OP_POPA
, NVS_OP_POPA
, -1, -1, -1);
744 shader
->InitInstruction
= NV40VPInitInstruction
;
745 shader
->SupportsOpcode
= NV40VPSupportsOpcode
;
746 shader
->SetOpcode
= NV40VPSetOpcode
;
747 shader
->SetCCUpdate
= NV40VPSetCCUpdate
;
748 shader
->SetCondition
= NV40VPSetCondition
;
749 shader
->SetResult
= NV40VPSetResult
;
750 shader
->SetSource
= NV40VPSetSource
;
751 shader
->SetLastInst
= NV40VPSetLastInst
;
752 shader
->SetBranchTarget
= NV40VPSetBranchTarget
;
754 shader
->HasMergedInst
= NV40VPHasMergedInst
;
755 shader
->GetOpcodeHW
= NV40VPGetOpcodeHW
;
757 shader
->GetDestFile
= NV40VPGetDestFile
;
758 shader
->GetDestID
= NV40VPGetDestID
;
759 shader
->GetDestMask
= NV40VPGetDestMask
;
761 shader
->GetSourceHW
= NV40VPGetSourceHW
;
762 shader
->GetSourceFile
= NV40VPGetSourceFile
;
763 shader
->GetSourceID
= NV40VPGetSourceID
;
764 shader
->GetSourceNegate
= NV40VPGetSourceNegate
;
765 shader
->GetSourceSwizzle
= NV40VPGetSourceSwizzle
;
766 shader
->GetSourceIndexed
= NV40VPGetSourceIndexed
;
768 shader
->GetRelAddressSwizzle
= NV40VPGetAddressRegSwizzle
;
770 shader
->SupportsConditional
= NV40VPSupportsConditional
;
771 shader
->GetConditionUpdate
= NV40VPGetConditionUpdate
;
772 shader
->GetConditionTest
= NV40VPGetConditionTest
;
773 shader
->GetCondition
= NV40VPGetCondition
;
774 shader
->GetCondRegSwizzle
= NV40VPGetCondRegSwizzle
;
775 shader
->GetCondRegID
= NV40VPGetCondRegID
;
777 shader
->GetBranch
= NV40VPGetBranch
;