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 /*****************************************************************************
13 NV30VPUploadToHW(GLcontext
*ctx
, nouveauShader
*nvs
)
15 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
18 /* We can do better here and keep more than one VP on the hardware, and
19 * switch between them with PROGRAM_START_ID..
21 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID
, 1);
23 for (i
=0; i
<nvs
->program_size
; i
+=4) {
24 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0
, 4);
25 OUT_RING(nvs
->program
[i
+ 0]);
26 OUT_RING(nvs
->program
[i
+ 1]);
27 OUT_RING(nvs
->program
[i
+ 2]);
28 OUT_RING(nvs
->program
[i
+ 3]);
30 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID
, 1);
33 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_IN_REG
, 2);
34 OUT_RING(nvs
->card_priv
.NV30VP
.vp_in_reg
);
35 OUT_RING(nvs
->card_priv
.NV30VP
.vp_out_reg
);
37 BEGIN_RING_CACHE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_SET_CLIPPING_PLANES
, 1);
38 OUT_RING_CACHE (nvs
->card_priv
.NV30VP
.clip_enables
);
42 NV30VPUpdateConst(GLcontext
*ctx
, nouveauShader
*nvs
, int id
)
44 nouveauContextPtr nmesa
= NOUVEAU_CONTEXT(ctx
);
47 val
= nvs
->params
[id
].source_val
?
48 nvs
->params
[id
].source_val
: nvs
->params
[id
].val
;
50 BEGIN_RING_SIZE(NvSub3D
, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID
, 5);
55 /*****************************************************************************
59 NV30VPSetBranchTarget(nvsFunc
*shader
, int addr
)
61 shader
->inst
[2] &= ~NV30_VP_INST_IADDR_MASK
;
62 shader
->inst
[2] |= (addr
<< NV30_VP_INST_IADDR_SHIFT
);
65 /*****************************************************************************
66 * Disassembly routines
69 NV30VPGetOpcodeHW(nvsFunc
* shader
, int slot
)
74 op
= (shader
->inst
[1] & NV30_VP_INST_SCA_OPCODEL_MASK
)
75 >> NV30_VP_INST_SCA_OPCODEL_SHIFT
;
76 op
|= ((shader
->inst
[0] & NV30_VP_INST_SCA_OPCODEH_MASK
)
77 >> NV30_VP_INST_SCA_OPCODEH_SHIFT
) << 4;
80 op
= (shader
->inst
[1] & NV30_VP_INST_VEC_OPCODE_MASK
)
81 >> NV30_VP_INST_VEC_OPCODE_SHIFT
;
88 NV30VPGetDestFile(nvsFunc
* shader
, int merged
)
90 switch (shader
->GetOpcode(shader
, merged
)) {
94 return NVS_FILE_ADDRESS
;
96 /*FIXME: This probably isn't correct.. */
97 if ((shader
->inst
[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK
) != 0)
98 return NVS_FILE_RESULT
;
99 if ((shader
->inst
[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK
) != 0)
100 return NVS_FILE_RESULT
;
101 return NVS_FILE_TEMP
;
106 NV30VPGetDestID(nvsFunc
* shader
, int merged
)
110 switch (shader
->GetDestFile(shader
, merged
)) {
111 case NVS_FILE_RESULT
:
112 id
= ((shader
->inst
[3] & NV30_VP_INST_DEST_ID_MASK
)
113 >> NV30_VP_INST_DEST_ID_SHIFT
);
115 case NV30_VP_INST_DEST_POS
: return NVS_FR_POSITION
;
116 case NV30_VP_INST_DEST_COL0
: return NVS_FR_COL0
;
117 case NV30_VP_INST_DEST_COL1
: return NVS_FR_COL1
;
118 case NV30_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0
;
119 case NV30_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1
;
120 case NV30_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2
;
121 case NV30_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3
;
122 case NV30_VP_INST_DEST_TC(4): return NVS_FR_TEXCOORD4
;
123 case NV30_VP_INST_DEST_TC(5): return NVS_FR_TEXCOORD5
;
124 case NV30_VP_INST_DEST_TC(6): return NVS_FR_TEXCOORD6
;
125 case NV30_VP_INST_DEST_TC(7): return NVS_FR_TEXCOORD7
;
129 case NVS_FILE_ADDRESS
:
131 return (shader
->inst
[0] & NV30_VP_INST_DEST_TEMP_ID_MASK
)
132 >> NV30_VP_INST_DEST_TEMP_ID_SHIFT
;
139 NV30VPGetDestMask(nvsFunc
* shader
, int merged
)
141 int hwmask
, mask
= 0;
143 if (shader
->GetDestFile(shader
, merged
) == NVS_FILE_RESULT
)
144 if (shader
->GetOpcodeSlot(shader
, merged
))
145 hwmask
= (shader
->inst
[3] & NV30_VP_INST_SDEST_WRITEMASK_MASK
)
146 >> NV30_VP_INST_SDEST_WRITEMASK_SHIFT
;
148 hwmask
= (shader
->inst
[3] & NV30_VP_INST_VDEST_WRITEMASK_MASK
)
149 >> NV30_VP_INST_VDEST_WRITEMASK_SHIFT
;
150 else if (shader
->GetOpcodeSlot(shader
, merged
))
151 hwmask
= (shader
->inst
[3] & NV30_VP_INST_STEMP_WRITEMASK_MASK
)
152 >> NV30_VP_INST_STEMP_WRITEMASK_SHIFT
;
154 hwmask
= (shader
->inst
[3] & NV30_VP_INST_VTEMP_WRITEMASK_MASK
)
155 >> NV30_VP_INST_VTEMP_WRITEMASK_SHIFT
;
157 if (hwmask
& (1 << 3)) mask
|= SMASK_X
;
158 if (hwmask
& (1 << 2)) mask
|= SMASK_Y
;
159 if (hwmask
& (1 << 1)) mask
|= SMASK_Z
;
160 if (hwmask
& (1 << 0)) mask
|= SMASK_W
;
166 NV30VPGetSourceID(nvsFunc
* shader
, int merged
, int pos
)
170 switch (shader
->GetSourceFile(shader
, merged
, pos
)) {
172 src
= shader
->GetSourceHW(shader
, merged
, pos
);
173 return ((src
& NV30_VP_SRC_REG_TEMP_ID_MASK
) >>
174 NV30_VP_SRC_REG_TEMP_ID_SHIFT
);
176 return ((shader
->inst
[1] & NV30_VP_INST_CONST_SRC_MASK
)
177 >> NV30_VP_INST_CONST_SRC_SHIFT
);
178 case NVS_FILE_ATTRIB
:
179 src
= ((shader
->inst
[1] & NV30_VP_INST_INPUT_SRC_MASK
)
180 >> NV30_VP_INST_INPUT_SRC_SHIFT
);
182 case NV30_VP_INST_IN_POS
: return NVS_FR_POSITION
;
183 case NV30_VP_INST_IN_COL0
: return NVS_FR_COL0
;
184 case NV30_VP_INST_IN_COL1
: return NVS_FR_COL1
;
185 case NV30_VP_INST_IN_TC(0): return NVS_FR_TEXCOORD0
;
186 case NV30_VP_INST_IN_TC(1): return NVS_FR_TEXCOORD1
;
187 case NV30_VP_INST_IN_TC(2): return NVS_FR_TEXCOORD2
;
188 case NV30_VP_INST_IN_TC(3): return NVS_FR_TEXCOORD3
;
189 case NV30_VP_INST_IN_TC(4): return NVS_FR_TEXCOORD4
;
190 case NV30_VP_INST_IN_TC(5): return NVS_FR_TEXCOORD5
;
191 case NV30_VP_INST_IN_TC(6): return NVS_FR_TEXCOORD6
;
192 case NV30_VP_INST_IN_TC(7): return NVS_FR_TEXCOORD7
;
194 return NVS_FR_UNKNOWN
;
202 NV30VPGetSourceAbs(nvsFunc
* shader
, int merged
, int pos
)
204 struct _op_xlat
*opr
;
205 static unsigned int abspos
[3] = {
206 NV30_VP_INST_SRC0_ABS
,
207 NV30_VP_INST_SRC1_ABS
,
208 NV30_VP_INST_SRC2_ABS
,
211 opr
= shader
->GetOPTXRec(shader
, merged
);
212 if (!opr
|| opr
->srcpos
[pos
] == -1 || opr
->srcpos
[pos
] > 2)
215 return ((shader
->inst
[0] & abspos
[opr
->srcpos
[pos
]]) ? 1 : 0);
219 NV30VPGetRelAddressRegID(nvsFunc
* shader
)
221 return ((shader
->inst
[0] & NV30_VP_INST_ADDR_REG_SELECT_1
) ? 1 : 0);
225 NV30VPGetRelAddressSwizzle(nvsFunc
* shader
)
229 swz
= NV20VP_TX_SWIZZLE
[(shader
->inst
[0] & NV30_VP_INST_ADDR_SWZ_MASK
)
230 >> NV30_VP_INST_ADDR_SWZ_SHIFT
];
235 NV30VPSupportsConditional(nvsFunc
* shader
)
237 /*FIXME: Is this true of all ops? */
242 NV30VPGetConditionUpdate(nvsFunc
* shader
)
244 return ((shader
->inst
[0] & NV30_VP_INST_COND_UPDATE_ENABLE
) ? 1 : 0);
248 NV30VPGetConditionTest(nvsFunc
* shader
)
252 /* The condition test is unconditionally enabled on some
253 * instructions. ie: the condition test bit does *NOT* have
256 * FIXME: check other relevant ops for this situation.
258 op
= shader
->GetOpcodeHW(shader
, 1);
260 case NV30_VP_INST_OP_BRA
:
263 return ((shader
->inst
[0] & NV30_VP_INST_COND_TEST_ENABLE
) ? 1 : 0);
268 NV30VPGetCondition(nvsFunc
* shader
)
272 cond
= ((shader
->inst
[0] & NV30_VP_INST_COND_MASK
)
273 >> NV30_VP_INST_COND_SHIFT
);
276 case NV30_VP_INST_COND_FL
: return NVS_COND_FL
;
277 case NV30_VP_INST_COND_LT
: return NVS_COND_LT
;
278 case NV30_VP_INST_COND_EQ
: return NVS_COND_EQ
;
279 case NV30_VP_INST_COND_LE
: return NVS_COND_LE
;
280 case NV30_VP_INST_COND_GT
: return NVS_COND_GT
;
281 case NV30_VP_INST_COND_NE
: return NVS_COND_NE
;
282 case NV30_VP_INST_COND_GE
: return NVS_COND_GE
;
283 case NV30_VP_INST_COND_TR
: return NVS_COND_TR
;
285 return NVS_COND_UNKNOWN
;
290 NV30VPGetCondRegSwizzle(nvsFunc
* shader
, nvsSwzComp
*swz
)
294 swzbits
= (shader
->inst
[0] & NV30_VP_INST_COND_SWZ_ALL_MASK
)
295 >> NV30_VP_INST_COND_SWZ_ALL_SHIFT
;
296 NV20VPTXSwizzle(swzbits
, swz
);
300 NV30VPGetCondRegID(nvsFunc
* shader
)
307 NV30VPGetBranch(nvsFunc
* shader
)
309 return ((shader
->inst
[2] & NV30_VP_INST_IADDR_MASK
)
310 >> NV30_VP_INST_IADDR_SHIFT
);
314 NV30VPInitShaderFuncs(nvsFunc
* shader
)
316 /* Inherit NV20 code, a lot of it is the same */
317 NV20VPInitShaderFuncs(shader
);
319 /* Increase max valid opcode ID, and add new instructions */
320 NVVP_TX_VOP_COUNT
= NVVP_TX_NVS_OP_COUNT
= 32;
322 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_FRC
, NVS_OP_FRC
, 0, -1, -1);
323 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_FLR
, NVS_OP_FLR
, 0, -1, -1);
324 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SEQ
, NVS_OP_SEQ
, 0, 1, -1);
325 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SFL
, NVS_OP_SFL
, 0, 1, -1);
326 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SGT
, NVS_OP_SGT
, 0, 1, -1);
327 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SLE
, NVS_OP_SLE
, 0, 1, -1);
328 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SNE
, NVS_OP_SNE
, 0, 1, -1);
329 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_STR
, NVS_OP_STR
, 0, 1, -1);
330 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_SSG
, NVS_OP_SSG
, 0, -1, -1);
331 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_ARR
, NVS_OP_ARR
, 0, -1, -1);
332 MOD_OPCODE(NVVP_TX_VOP
, NV30_VP_INST_OP_ARA
, NVS_OP_ARA
, 3, -1, -1);
334 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_BRA
, NVS_OP_BRA
, -1, -1, -1);
335 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_CAL
, NVS_OP_CAL
, -1, -1, -1);
336 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_RET
, NVS_OP_RET
, -1, -1, -1);
337 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_LG2
, NVS_OP_LG2
, 2, -1, -1);
338 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_EX2
, NVS_OP_EX2
, 2, -1, -1);
339 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_SIN
, NVS_OP_SIN
, 2, -1, -1);
340 MOD_OPCODE(NVVP_TX_SOP
, NV30_VP_INST_OP_COS
, NVS_OP_COS
, 2, -1, -1);
342 shader
->UploadToHW
= NV30VPUploadToHW
;
343 shader
->UpdateConst
= NV30VPUpdateConst
;
345 shader
->GetOpcodeHW
= NV30VPGetOpcodeHW
;
347 shader
->GetDestFile
= NV30VPGetDestFile
;
348 shader
->GetDestID
= NV30VPGetDestID
;
349 shader
->GetDestMask
= NV30VPGetDestMask
;
351 shader
->GetSourceID
= NV30VPGetSourceID
;
352 shader
->GetSourceAbs
= NV30VPGetSourceAbs
;
354 shader
->GetRelAddressRegID
= NV30VPGetRelAddressRegID
;
355 shader
->GetRelAddressSwizzle
= NV30VPGetRelAddressSwizzle
;
357 shader
->SupportsConditional
= NV30VPSupportsConditional
;
358 shader
->GetConditionUpdate
= NV30VPGetConditionUpdate
;
359 shader
->GetConditionTest
= NV30VPGetConditionTest
;
360 shader
->GetCondition
= NV30VPGetCondition
;
361 shader
->GetCondRegSwizzle
= NV30VPGetCondRegSwizzle
;
362 shader
->GetCondRegID
= NV30VPGetCondRegID
;
364 shader
->GetBranch
= NV30VPGetBranch
;
365 shader
->SetBranchTarget
= NV30VPSetBranchTarget
;