1 #include "nouveau_context.h"
2 #include "nouveau_object.h"
3 #include "nouveau_fifo.h"
4 #include "nouveau_reg.h"
6 #include "nouveau_shader.h"
7 #include "nv30_shader.h"
9 extern nvsSwzComp NV20VP_TX_SWIZZLE
[4];
10 extern void NV20VPTXSwizzle(int hwswz
, nvsSwzComp
*swz
);
12 /*****************************************************************************
16 NV30VPUploadToHW(GLcontext
*ctx
, nouveauShader
*nvs
)
18 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
21 /* We can do better here and keep more than one VP on the hardware, and
22 * switch between them with PROGRAM_START_ID..
24 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID
, 1);
26 for (i
=0; i
<nvs
->program_size
; i
+=4) {
27 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0
, 4);
28 OUT_RING(nvs
->program
[i
+ 0]);
29 OUT_RING(nvs
->program
[i
+ 1]);
30 OUT_RING(nvs
->program
[i
+ 2]);
31 OUT_RING(nvs
->program
[i
+ 3]);
33 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID
, 1);
38 NV30VPUpdateConst(GLcontext
*ctx
, nouveauShader
*nvs
, int id
)
40 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
43 val
= nvs
->params
[id
].source_val
?
44 nvs
->params
[id
].source_val
: nvs
->params
[id
].val
;
46 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID
, 5);
51 /*****************************************************************************
55 /*****************************************************************************
56 * Disassembly routines
59 NV30VPGetOpcodeHW(nvsFunc
* shader
, int slot
)
64 op
= (shader
->inst
[1] & NV30_VP_INST_SCA_OPCODEL_MASK
)
65 >> NV30_VP_INST_SCA_OPCODEL_SHIFT
;
66 op
|= ((shader
->inst
[0] & NV30_VP_INST_SCA_OPCODEH_MASK
)
67 >> NV30_VP_INST_SCA_OPCODEH_SHIFT
) << 4;
70 op
= (shader
->inst
[1] & NV30_VP_INST_VEC_OPCODE_MASK
)
71 >> NV30_VP_INST_VEC_OPCODE_SHIFT
;
78 NV30VPGetDestFile(nvsFunc
* shader
, int merged
)
80 switch (shader
->GetOpcode(shader
, merged
)) {
84 return NVS_FILE_ADDRESS
;
86 /*FIXME: This probably isn't correct.. */
87 if ((shader
->inst
[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK
) != 0)
88 return NVS_FILE_RESULT
;
89 if ((shader
->inst
[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK
) != 0)
90 return NVS_FILE_RESULT
;
96 NV30VPGetDestID(nvsFunc
* shader
, int merged
)
100 switch (shader
->GetDestFile(shader
, merged
)) {
101 case NVS_FILE_RESULT
:
102 id
= ((shader
->inst
[3] & NV30_VP_INST_DEST_ID_MASK
)
103 >> NV30_VP_INST_DEST_ID_SHIFT
);
105 case NV30_VP_INST_DEST_POS
: return NVS_FR_POSITION
;
106 case NV30_VP_INST_DEST_COL0
: return NVS_FR_COL0
;
107 case NV30_VP_INST_DEST_COL1
: return NVS_FR_COL1
;
108 case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0
;
109 case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1
;
110 case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2
;
111 case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3
;
112 case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4
;
113 case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5
;
114 case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6
;
115 case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7
;
119 case NVS_FILE_ADDRESS
:
121 return (shader
->inst
[0] & NV30_VP_INST_DEST_TEMP_ID_MASK
)
122 >> NV30_VP_INST_DEST_TEMP_ID_SHIFT
;
129 NV30VPGetDestMask(nvsFunc
* shader
, int merged
)
131 int hwmask
, mask
= 0;
133 if (shader
->GetDestFile(shader
, merged
) == NVS_FILE_RESULT
)
134 if (shader
->GetOpcodeSlot(shader
, merged
))
135 hwmask
= (shader
->inst
[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK
)
136 >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT
;
138 hwmask
= (shader
->inst
[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK
)
139 >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT
;
140 else if (shader
->GetOpcodeSlot(shader
, merged
))
141 hwmask
= (shader
->inst
[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK
)
142 >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT
;
144 hwmask
= (shader
->inst
[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK
)
145 >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT
;
147 if (hwmask
& (1 << 3)) mask
|= SMASK_X
;
148 if (hwmask
& (1 << 2)) mask
|= SMASK_Y
;
149 if (hwmask
& (1 << 1)) mask
|= SMASK_Z
;
150 if (hwmask
& (1 << 0)) mask
|= SMASK_W
;
156 NV30VPGetSourceID(nvsFunc
* shader
, int merged
, int pos
)
160 switch (shader
->GetSourceFile(shader
, merged
, pos
)) {
162 src
= shader
->GetSourceHW(shader
, merged
, pos
);
163 return ((src
& NV30_VP_SRC_REG_TEMP_ID_MASK
) >>
164 NV30_VP_SRC_REG_TEMP_ID_SHIFT
);
166 return ((shader
->inst
[1] & NV30_VP_INST_CONST_SRC_MASK
)
167 >> NV30_VP_INST_CONST_SRC_SHIFT
);
168 case NVS_FILE_ATTRIB
:
169 src
= ((shader
->inst
[1] & NV30_VP_INST_INPUT_SRC_MASK
)
170 >> NV30_VP_INST_INPUT_SRC_SHIFT
);
172 case NV30_VP_INST_IN_POS
: return NVS_FR_POSITION
;
173 case NV30_VP_INST_IN_COL0
: return NVS_FR_COL0
;
174 case NV30_VP_INST_IN_COL1
: return NVS_FR_COL1
;
175 case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0
;
176 case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1
;
177 case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2
;
178 case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3
;
179 case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4
;
180 case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5
;
181 case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6
;
182 case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7
;
184 return NVS_FR_UNKNOWN
;
192 NV30VPGetSourceAbs(nvsFunc
* shader
, int merged
, int pos
)
194 struct _op_xlat
*opr
;
195 static unsigned int abspos
[3] = {
196 NV30_VP_INST_SRC0_ABS
,
197 NV30_VP_INST_SRC1_ABS
,
198 NV30_VP_INST_SRC2_ABS
,
201 opr
= shader
->GetOPTXRec(shader
, merged
);
202 if (!opr
|| opr
->srcpos
[pos
] == -1 || opr
->srcpos
[pos
] > 2)
205 return ((shader
->inst
[0] & abspos
[opr
->srcpos
[pos
]]) ? 1 : 0);
209 NV30VPGetRelAddressRegID(nvsFunc
* shader
)
211 return ((shader
->inst
[0] & NV30_VP_INST_ADDR_REG_SELECT_1
) ? 1 : 0);
215 NV30VPGetRelAddressSwizzle(nvsFunc
* shader
)
219 swz
= NV20VP_TX_SWIZZLE
[(shader
->inst
[0] & NV30_VP_INST_ADDR_SWZ_MASK
)
220 >> NV30_VP_INST_ADDR_SWZ_SHIFT
];
225 NV30VPSupportsConditional(nvsFunc
* shader
)
227 /*FIXME: Is this true of all ops? */
232 NV30VPGetConditionUpdate(nvsFunc
* shader
)
234 return ((shader
->inst
[0] & NV30_VP_INST_COND_UPDATE_ENABLE
) ? 1 : 0);
238 NV30VPGetConditionTest(nvsFunc
* shader
)
242 /* The condition test is unconditionally enabled on some
243 * instructions. ie: the condition test bit does *NOT* have
246 * FIXME: check other relevant ops for this situation.
248 op
= shader
->GetOpcodeHW(shader
, 1);
250 case NV30_VP_INST_OP_BRA
:
253 return ((shader
->inst
[0] & NV30_VP_INST_COND_TEST_ENABLE
) ? 1 : 0);
258 NV30VPGetCondition(nvsFunc
* shader
)
262 cond
= ((shader
->inst
[0] & NV30_VP_INST_COND_MASK
)
263 >> NV30_VP_INST_COND_SHIFT
);
266 case NV30_VP_INST_COND_FL
: return NVS_COND_FL
;
267 case NV30_VP_INST_COND_LT
: return NVS_COND_LT
;
268 case NV30_VP_INST_COND_EQ
: return NVS_COND_EQ
;
269 case NV30_VP_INST_COND_LE
: return NVS_COND_LE
;
270 case NV30_VP_INST_COND_GT
: return NVS_COND_GT
;
271 case NV30_VP_INST_COND_NE
: return NVS_COND_NE
;
272 case NV30_VP_INST_COND_GE
: return NVS_COND_GE
;
273 case NV30_VP_INST_COND_TR
: return NVS_COND_TR
;
275 return NVS_COND_UNKNOWN
;
280 NV30VPGetCondRegSwizzle(nvsFunc
* shader
, nvsSwzComp
*swz
)
284 swzbits
= (shader
->inst
[0] & NV30_VP_INST_COND_SWZ_ALL_MASK
)
285 >> NV30_VP_INST_COND_SWZ_ALL_SHIFT
;
286 NV20VPTXSwizzle(swzbits
, swz
);
290 NV30VPGetCondRegID(nvsFunc
* shader
)
297 NV30VPGetBranch(nvsFunc
* shader
)
299 return ((shader
->inst
[2] & NV30_VP_INST_IADDR_MASK
)
300 >> NV30_VP_INST_IADDR_SHIFT
);
304 NV30VPInitShaderFuncs(nvsFunc
* shader
)
306 /* Inherit NV20 code, a lot of it is the same */
307 NV20VPInitShaderFuncs(shader
);
309 /* Increase max valid opcode ID, and add new instructions */
310 NVVP_TX_VOP_COUNT
= NVVP_TX_NVS_OP_COUNT
= 32;
312 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_FRC
, NVS_OP_FRC
, 0, -1, -1);
313 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_FLR
, NVS_OP_FLR
, 0, -1, -1);
314 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SEQ
, NVS_OP_SEQ
, 0, 1, -1);
315 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SFL
, NVS_OP_SFL
, 0, 1, -1);
316 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SGT
, NVS_OP_SGT
, 0, 1, -1);
317 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SLE
, NVS_OP_SLE
, 0, 1, -1);
318 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SNE
, NVS_OP_SNE
, 0, 1, -1);
319 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_STR
, NVS_OP_STR
, 0, 1, -1);
320 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SSG
, NVS_OP_SSG
, 0, -1, -1);
321 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_ARR
, NVS_OP_ARR
, 0, -1, -1);
322 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_ARA
, NVS_OP_ARA
, 3, -1, -1);
324 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_BRA
, NVS_OP_BRA
, -1, -1, -1);
325 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_CAL
, NVS_OP_CAL
, -1, -1, -1);
326 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_RET
, NVS_OP_RET
, -1, -1, -1);
327 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_LG2
, NVS_OP_LG2
, 2, -1, -1);
328 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_EX2
, NVS_OP_EX2
, 2, -1, -1);
329 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_SIN
, NVS_OP_SIN
, 2, -1, -1);
330 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_COS
, NVS_OP_COS
, 2, -1, -1);
332 shader
->UploadToHW
= NV30VPUploadToHW
;
333 shader
->UpdateConst
= NV30VPUpdateConst
;
335 shader
->GetOpcodeHW
= NV30VPGetOpcodeHW
;
337 shader
->GetDestFile
= NV30VPGetDestFile
;
338 shader
->GetDestID
= NV30VPGetDestID
;
339 shader
->GetDestMask
= NV30VPGetDestMask
;
341 shader
->GetSourceID
= NV30VPGetSourceID
;
342 shader
->GetSourceAbs
= NV30VPGetSourceAbs
;
344 shader
->GetRelAddressRegID
= NV30VPGetRelAddressRegID
;
345 shader
->GetRelAddressSwizzle
= NV30VPGetRelAddressSwizzle
;
347 shader
->SupportsConditional
= NV30VPSupportsConditional
;
348 shader
->GetConditionUpdate
= NV30VPGetConditionUpdate
;
349 shader
->GetConditionTest
= NV30VPGetConditionTest
;
350 shader
->GetCondition
= NV30VPGetCondition
;
351 shader
->GetCondRegSwizzle
= NV30VPGetCondRegSwizzle
;
352 shader
->GetCondRegID
= NV30VPGetCondRegID
;
354 shader
->GetBranch
= NV30VPGetBranch
;