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;