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 "nv20_shader.h"
9
unsigned int NVVP_TX_VOP_COUNT = 16;
10
unsigned int NVVP_TX_NVS_OP_COUNT = 16;
11
struct _op_xlat NVVP_TX_VOP[32];
12
struct _op_xlat NVVP_TX_SOP[32];
14
nvsSwzComp NV20VP_TX_SWIZZLE[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
16
/*****************************************************************************
20
NV20VPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
22
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
25
/* XXX: missing a way to say what insn we're uploading from, and possible
26
* the program start position (if NV20 has one) */
27
for (i=0; i<nvs->program_size; i+=4) {
28
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4);
29
OUT_RING(nvs->program[i + 0]);
30
OUT_RING(nvs->program[i + 1]);
31
OUT_RING(nvs->program[i + 2]);
32
OUT_RING(nvs->program[i + 3]);
37
NV20VPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
39
nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
41
/* Worth checking if the value *actually* changed? Mesa doesn't tell us this
44
BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_ID, 1);
46
BEGIN_RING_SIZE(NvSub3D, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4);
47
OUT_RINGf(nvs->params[id].source_val[0]);
48
OUT_RINGf(nvs->params[id].source_val[1]);
49
OUT_RINGf(nvs->params[id].source_val[2]);
50
OUT_RINGf(nvs->params[id].source_val[3]);
53
/*****************************************************************************
57
/*****************************************************************************
58
* Disassembly routines
61
NV20VPTXSwizzle(int hwswz, nvsSwzComp *swz)
63
swz[NVS_SWZ_X] = NV20VP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
64
swz[NVS_SWZ_Y] = NV20VP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
65
swz[NVS_SWZ_Z] = NV20VP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
66
swz[NVS_SWZ_W] = NV20VP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
70
NV20VPHasMergedInst(nvsFunc * shader)
72
if (shader->GetOpcodeHW(shader, 0) != NV20_VP_INST_OPCODE_NOP &&
73
shader->GetOpcodeHW(shader, 1) != NV20_VP_INST_OPCODE_NOP)
75
("\n\n*****both opcode fields have values - PLEASE REPORT*****\n");
80
NV20VPIsLastInst(nvsFunc * shader)
82
return ((shader->inst[3] & (1 << 0)) ? 1 : 0);
86
NV20VPGetOffsetNext(nvsFunc * shader)
91
static struct _op_xlat *
92
NV20VPGetOPTXRec(nvsFunc * shader, int merged)
97
if (shader->GetOpcodeSlot(shader, merged)) {
99
op = shader->GetOpcodeHW(shader, 1);
100
if (op >= NVVP_TX_NVS_OP_COUNT)
105
op = shader->GetOpcodeHW(shader, 0);
106
if (op >= NVVP_TX_VOP_COUNT)
110
if (opr[op].SOP == NVS_OP_UNKNOWN)
115
static struct _op_xlat *
116
NV20VPGetOPTXFromSOP(nvsOpcode sop, int *id)
120
for (i=0;i<NVVP_TX_VOP_COUNT;i++) {
121
if (NVVP_TX_VOP[i].SOP == sop) {
123
return &NVVP_TX_VOP[i];
127
for (i=0;i<NVVP_TX_NVS_OP_COUNT;i++) {
128
if (NVVP_TX_SOP[i].SOP == sop) {
130
return &NVVP_TX_SOP[i];
138
NV20VPGetOpcodeSlot(nvsFunc * shader, int merged)
140
if (shader->HasMergedInst(shader))
142
if (shader->GetOpcodeHW(shader, 0) == NV20_VP_INST_OPCODE_NOP)
148
NV20VPGetOpcode(nvsFunc * shader, int merged)
150
struct _op_xlat *opr;
152
opr = shader->GetOPTXRec(shader, merged);
154
return NVS_OP_UNKNOWN;
160
NV20VPGetOpcodeHW(nvsFunc * shader, int slot)
163
return (shader->inst[1] & NV20_VP_INST_SCA_OPCODE_MASK)
164
>> NV20_VP_INST_SCA_OPCODE_SHIFT;
165
return (shader->inst[1] & NV20_VP_INST_VEC_OPCODE_MASK)
166
>> NV20_VP_INST_VEC_OPCODE_SHIFT;
170
NV20VPGetDestFile(nvsFunc * shader, int merged)
172
switch (shader->GetOpcode(shader, merged)) {
174
return NVS_FILE_ADDRESS;
176
/*FIXME: This probably isn't correct.. */
177
if ((shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK) == 0)
178
return NVS_FILE_TEMP;
179
return NVS_FILE_RESULT;
184
NV20VPGetDestID(nvsFunc * shader, int merged)
188
switch (shader->GetDestFile(shader, merged)) {
189
case NVS_FILE_RESULT:
190
id = ((shader->inst[3] & NV20_VP_INST_DEST_MASK)
191
>> NV20_VP_INST_DEST_SHIFT);
193
case NV20_VP_INST_DEST_POS : return NVS_FR_POSITION;
194
case NV20_VP_INST_DEST_COL0 : return NVS_FR_COL0;
195
case NV20_VP_INST_DEST_COL1 : return NVS_FR_COL1;
196
case NV20_VP_INST_DEST_TC(0): return NVS_FR_TEXCOORD0;
197
case NV20_VP_INST_DEST_TC(1): return NVS_FR_TEXCOORD1;
198
case NV20_VP_INST_DEST_TC(2): return NVS_FR_TEXCOORD2;
199
case NV20_VP_INST_DEST_TC(3): return NVS_FR_TEXCOORD3;
203
case NVS_FILE_ADDRESS:
206
id = ((shader->inst[3] & NV20_VP_INST_DEST_TEMP_ID_MASK)
207
>> NV20_VP_INST_DEST_TEMP_ID_SHIFT);
215
NV20VPGetDestMask(nvsFunc * shader, int merged)
217
int hwmask, mask = 0;
219
/* Special handling for ARL - hardware only supports a
220
* 1-component address reg
222
if (shader->GetOpcode(shader, merged) == NVS_OP_ARL)
225
if (shader->GetDestFile(shader, merged) == NVS_FILE_RESULT)
226
hwmask = (shader->inst[3] & NV20_VP_INST_DEST_WRITEMASK_MASK)
227
>> NV20_VP_INST_DEST_WRITEMASK_SHIFT;
228
else if (shader->GetOpcodeSlot(shader, merged))
229
hwmask = (shader->inst[3] & NV20_VP_INST_STEMP_WRITEMASK_MASK)
230
>> NV20_VP_INST_STEMP_WRITEMASK_SHIFT;
232
hwmask = (shader->inst[3] & NV20_VP_INST_VTEMP_WRITEMASK_MASK)
233
>> NV20_VP_INST_VTEMP_WRITEMASK_SHIFT;
235
if (hwmask & (1 << 3)) mask |= SMASK_X;
236
if (hwmask & (1 << 2)) mask |= SMASK_Y;
237
if (hwmask & (1 << 1)) mask |= SMASK_Z;
238
if (hwmask & (1 << 0)) mask |= SMASK_W;
244
NV20VPGetSourceHW(nvsFunc * shader, int merged, int pos)
246
struct _op_xlat *opr;
249
opr = shader->GetOPTXRec(shader, merged);
253
switch (opr->srcpos[pos]) {
255
src = ((shader->inst[1] & NV20_VP_INST_SRC0H_MASK)
256
>> NV20_VP_INST_SRC0H_SHIFT)
257
<< NV20_VP_SRC0_HIGH_SHIFT;
258
src |= ((shader->inst[2] & NV20_VP_INST_SRC0L_MASK)
259
>> NV20_VP_INST_SRC0L_SHIFT);
262
src = ((shader->inst[2] & NV20_VP_INST_SRC1_MASK)
263
>> NV20_VP_INST_SRC1_SHIFT);
266
src = ((shader->inst[2] & NV20_VP_INST_SRC2H_MASK)
267
>> NV20_VP_INST_SRC2H_SHIFT)
268
<< NV20_VP_SRC2_HIGH_SHIFT;
269
src |= ((shader->inst[3] & NV20_VP_INST_SRC2L_MASK)
270
>> NV20_VP_INST_SRC2L_SHIFT);
280
NV20VPGetSourceFile(nvsFunc * shader, int merged, int pos)
283
struct _op_xlat *opr;
286
opr = shader->GetOPTXRec(shader, merged);
287
if (!opr || opr->srcpos[pos] == -1)
290
switch (opr->srcpos[pos]) {
292
return NVS_FILE_ADDRESS;
294
src = NV20VPGetSourceHW(shader, merged, pos);
295
file = (src & NV20_VP_SRC_REG_TYPE_MASK) >> NV20_VP_SRC_REG_TYPE_SHIFT;
298
case NV20_VP_SRC_REG_TYPE_TEMP : return NVS_FILE_TEMP;
299
case NV20_VP_SRC_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
300
case NV20_VP_SRC_REG_TYPE_CONST: return NVS_FILE_CONST;
302
return NVS_FILE_UNKNOWN;
308
NV20VPGetSourceID(nvsFunc * shader, int merged, int pos)
312
switch (shader->GetSourceFile(shader, merged, pos)) {
314
src = shader->GetSourceHW(shader, merged, pos);
315
return ((src & NV20_VP_SRC_REG_TEMP_ID_MASK) >>
316
NV20_VP_SRC_REG_TEMP_ID_SHIFT);
318
return ((shader->inst[1] & NV20_VP_INST_CONST_SRC_MASK)
319
>> NV20_VP_INST_CONST_SRC_SHIFT);
320
case NVS_FILE_ATTRIB:
321
src = ((shader->inst[1] & NV20_VP_INST_INPUT_SRC_MASK)
322
>> NV20_VP_INST_INPUT_SRC_SHIFT);
324
case NV20_VP_INST_INPUT_SRC_POS : return NVS_FR_POSITION;
325
case NV20_VP_INST_INPUT_SRC_COL0 : return NVS_FR_COL0;
326
case NV20_VP_INST_INPUT_SRC_COL1 : return NVS_FR_COL1;
327
case NV20_VP_INST_INPUT_SRC_TC(0): return NVS_FR_TEXCOORD0;
328
case NV20_VP_INST_INPUT_SRC_TC(1): return NVS_FR_TEXCOORD1;
329
case NV20_VP_INST_INPUT_SRC_TC(2): return NVS_FR_TEXCOORD2;
330
case NV20_VP_INST_INPUT_SRC_TC(3): return NVS_FR_TEXCOORD3;
332
return NVS_FR_UNKNOWN;
340
NV20VPGetSourceNegate(nvsFunc * shader, int merged, int pos)
344
src = shader->GetSourceHW(shader, merged, pos);
346
return ((src & NV20_VP_SRC_REG_NEGATE) ? 1 : 0);
350
NV20VPGetSourceAbs(nvsFunc * shader, int merged, int pos)
352
/* NV20 can't do ABS on sources? Appears to be emulated with
359
NV20VPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
364
src = shader->GetSourceHW(shader, merged, pos);
366
(src & NV20_VP_SRC_REG_SWZ_ALL_MASK) >> NV20_VP_SRC_REG_SWZ_ALL_SHIFT;
367
return NV20VPTXSwizzle(swzbits, swz);
371
NV20VPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
373
/* I don't think NV20 can index into attribs, at least no GL
374
* extension is exposed that will allow it.
376
if (shader->GetSourceFile(shader, merged, pos) != NVS_FILE_CONST)
378
if (shader->inst[3] & NV20_VP_INST_INDEX_CONST)
384
NV20VPGetAddressRegID(nvsFunc * shader)
386
/* Only 1 address reg */
391
NV20VPGetAddressRegSwizzle(nvsFunc * shader)
393
/* Only A0.x available */
398
NV20VPInitShaderFuncs(nvsFunc * shader)
400
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
401
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
402
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
403
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ADD, NVS_OP_ADD, 0, 2, -1);
404
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
405
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
406
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DPH, NVS_OP_DPH, 0, 1, -1);
407
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
408
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
409
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
410
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
411
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
412
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
413
MOD_OPCODE(NVVP_TX_VOP, NV20_VP_INST_OPCODE_ARL, NVS_OP_ARL, 0, -1, -1);
415
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
416
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCP, NVS_OP_RCP, 2, -1, -1);
417
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RCC, NVS_OP_RCC, 2, -1, -1);
418
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_RSQ, NVS_OP_RSQ, 2, -1, -1);
419
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_EXP, NVS_OP_EXP, 2, -1, -1);
420
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LOG, NVS_OP_LOG, 2, -1, -1);
421
MOD_OPCODE(NVVP_TX_SOP, NV20_VP_INST_OPCODE_LIT, NVS_OP_LIT, 2, -1, -1);
423
shader->UploadToHW = NV20VPUploadToHW;
424
shader->UpdateConst = NV20VPUpdateConst;
426
shader->GetOPTXRec = NV20VPGetOPTXRec;
427
shader->GetOPTXFromSOP = NV20VPGetOPTXFromSOP;
429
shader->HasMergedInst = NV20VPHasMergedInst;
430
shader->IsLastInst = NV20VPIsLastInst;
431
shader->GetOffsetNext = NV20VPGetOffsetNext;
432
shader->GetOpcodeSlot = NV20VPGetOpcodeSlot;
433
shader->GetOpcode = NV20VPGetOpcode;
434
shader->GetOpcodeHW = NV20VPGetOpcodeHW;
435
shader->GetDestFile = NV20VPGetDestFile;
436
shader->GetDestID = NV20VPGetDestID;
437
shader->GetDestMask = NV20VPGetDestMask;
438
shader->GetSourceHW = NV20VPGetSourceHW;
439
shader->GetSourceFile = NV20VPGetSourceFile;
440
shader->GetSourceID = NV20VPGetSourceID;
441
shader->GetSourceNegate = NV20VPGetSourceNegate;
442
shader->GetSourceAbs = NV20VPGetSourceAbs;
443
shader->GetSourceSwizzle = NV20VPGetSourceSwizzle;
444
shader->GetSourceIndexed = NV20VPGetSourceIndexed;
445
shader->GetRelAddressRegID = NV20VPGetAddressRegID;
446
shader->GetRelAddressSwizzle = NV20VPGetAddressRegSwizzle;