Merge branch 'master' of git+ssh://znh@git.freedesktop.org/git/mesa/mesa
[mesa.git] / src / mesa / drivers / dri / nouveau / nv30_fragprog.c
1 #include <stdint.h>
2
3 #include "glheader.h"
4 #include "macros.h"
5
6 #include "nouveau_context.h"
7 #include "nouveau_fifo.h"
8 #include "nouveau_reg.h"
9 #include "nouveau_drm.h"
10 #include "nouveau_shader.h"
11 #include "nouveau_object.h"
12 #include "nouveau_msg.h"
13 #include "nouveau_bufferobj.h"
14 #include "nv30_shader.h"
15
16 unsigned int NVFP_TX_AOP_COUNT = 64;
17 struct _op_xlat NVFP_TX_AOP[64];
18
19 /*******************************************************************************
20 * Support routines
21 */
22
23 static void
24 NV30FPUploadToHW(GLcontext *ctx, nouveauShader *nvs)
25 {
26 nouveauContextPtr nmesa = NOUVEAU_CONTEXT(ctx);
27 uint32_t offset;
28
29 if (!nvs->program_buffer)
30 nvs->program_buffer = ctx->Driver.NewBufferObject(ctx, 0,
31 GL_ARRAY_BUFFER_ARB);
32
33 /* Should use STATIC_DRAW_ARB if shader doesn't use changable params */
34 ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER_ARB,
35 nvs->program_size * sizeof(uint32_t),
36 (const GLvoid *)nvs->program,
37 GL_DYNAMIC_DRAW_ARB,
38 nvs->program_buffer);
39
40 offset = nouveau_bufferobj_gpu_ref(ctx, GL_READ_ONLY_ARB,
41 nvs->program_buffer);
42
43 /* Not using state cache here, updated programs at the same address don't
44 * seem to take effect unless the ACTIVE_PROGRAM method is called again.
45 * HW caches the program somewhere?
46 */
47 BEGIN_RING_SIZE(NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1);
48 OUT_RING (offset | 1);
49 BEGIN_RING_SIZE(NvSub3D, 0x1d60, 1);
50 OUT_RING (nvs->card_priv.NV30FP.fp_control | 0x03000000);
51 }
52
53 static void
54 NV30FPUpdateConst(GLcontext *ctx, nouveauShader *nvs, int id)
55 {
56 uint32_t *new = nvs->params[id].source_val ?
57 (uint32_t*)nvs->params[id].source_val : (uint32_t*)nvs->params[id].val;
58 uint32_t *current;
59 int i;
60
61 for (i=0; i<nvs->params[id].hw_index_cnt; i++) {
62 current = nvs->program + nvs->params[id].hw_index[i];
63 COPY_4V(current, new);
64 }
65 nvs->on_hardware = 0;
66 }
67
68 /*******************************************************************************
69 * Assembly helpers
70 */
71 static struct _op_xlat *
72 NV30FPGetOPTXFromSOP(nvsOpcode op, int *id)
73 {
74 int i;
75
76 for (i=0; i<NVFP_TX_AOP_COUNT; i++) {
77 if (NVFP_TX_AOP[i].SOP == op) {
78 if (id) *id = 0;
79 return &NVFP_TX_AOP[i];
80 }
81 }
82
83 return NULL;
84 }
85
86 static int
87 NV30FPSupportsOpcode(nvsFunc *shader, nvsOpcode op)
88 {
89 if (shader->GetOPTXFromSOP(op, NULL))
90 return 1;
91 return 0;
92 }
93
94 static void
95 NV30FPSetOpcode(nvsFunc *shader, unsigned int opcode, int slot)
96 {
97 if (opcode == NV30_FP_OP_OPCODE_KIL)
98 shader->card_priv->NV30FP.fp_control |= (1<<7);
99 shader->inst[0] &= ~NV30_FP_OP_OPCODE_MASK;
100 shader->inst[0] |= (opcode << NV30_FP_OP_OPCODE_SHIFT);
101 }
102
103 static void
104 NV30FPSetCCUpdate(nvsFunc *shader)
105 {
106 shader->inst[0] |= NV30_FP_OP_COND_WRITE_ENABLE;
107 }
108
109 static void
110 NV30FPSetCondition(nvsFunc *shader, int on, nvsCond cond, int reg,
111 nvsSwzComp *swz)
112 {
113 nvsSwzComp default_swz[4] = { NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
114 unsigned int hwcond;
115
116 /* cond masking is always enabled */
117 if (!on) {
118 cond = NVS_COND_TR;
119 reg = 0;
120 swz = default_swz;
121 }
122
123 switch (cond) {
124 case NVS_COND_TR: hwcond = NV30_FP_OP_COND_TR; break;
125 case NVS_COND_FL: hwcond = NV30_FP_OP_COND_FL; break;
126 case NVS_COND_LT: hwcond = NV30_FP_OP_COND_LT; break;
127 case NVS_COND_GT: hwcond = NV30_FP_OP_COND_GT; break;
128 case NVS_COND_LE: hwcond = NV30_FP_OP_COND_LE; break;
129 case NVS_COND_GE: hwcond = NV30_FP_OP_COND_GE; break;
130 case NVS_COND_EQ: hwcond = NV30_FP_OP_COND_EQ; break;
131 case NVS_COND_NE: hwcond = NV30_FP_OP_COND_NE; break;
132 default:
133 WARN_ONCE("unknown fp condmask=%d\n", cond);
134 hwcond = NV30_FP_OP_COND_TR;
135 break;
136 }
137
138 shader->inst[1] &= ~NV30_FP_OP_COND_MASK;
139 shader->inst[1] |= (hwcond << NV30_FP_OP_COND_SHIFT);
140
141 shader->inst[1] &= ~NV30_FP_OP_COND_SWZ_ALL_MASK;
142 shader->inst[1] |= (swz[NVS_SWZ_X] << NV30_FP_OP_COND_SWZ_X_SHIFT);
143 shader->inst[1] |= (swz[NVS_SWZ_Y] << NV30_FP_OP_COND_SWZ_Y_SHIFT);
144 shader->inst[1] |= (swz[NVS_SWZ_Z] << NV30_FP_OP_COND_SWZ_Z_SHIFT);
145 shader->inst[1] |= (swz[NVS_SWZ_W] << NV30_FP_OP_COND_SWZ_W_SHIFT);
146 }
147
148 static void
149 NV30FPSetResult(nvsFunc *shader, nvsRegister *reg, unsigned int mask, int slot)
150 {
151 unsigned int hwreg;
152
153 if (mask & SMASK_X) shader->inst[0] |= NV30_FP_OP_OUT_X;
154 if (mask & SMASK_Y) shader->inst[0] |= NV30_FP_OP_OUT_Y;
155 if (mask & SMASK_Z) shader->inst[0] |= NV30_FP_OP_OUT_Z;
156 if (mask & SMASK_W) shader->inst[0] |= NV30_FP_OP_OUT_W;
157
158 if (reg->file == NVS_FILE_RESULT) {
159 hwreg = 0; /* FIXME: this is only fragment.color */
160 /* This is *not* correct, I have no idea what it is either */
161 shader->inst[0] |= NV30_FP_OP_UNK0_7;
162 } else {
163 shader->inst[0] &= ~NV30_FP_OP_UNK0_7;
164 hwreg = reg->index;
165 }
166 shader->inst[0] &= ~NV30_FP_OP_OUT_REG_SHIFT;
167 shader->inst[0] |= (hwreg << NV30_FP_OP_OUT_REG_SHIFT);
168 }
169
170 static void
171 NV30FPSetSource(nvsFunc *shader, nvsRegister *reg, int pos)
172 {
173 unsigned int hwsrc = 0;
174
175 switch (reg->file) {
176 case NVS_FILE_TEMP:
177 hwsrc |= (NV30_FP_REG_TYPE_TEMP << NV30_FP_REG_TYPE_SHIFT);
178 hwsrc |= (reg->index << NV30_FP_REG_SRC_SHIFT);
179 break;
180 case NVS_FILE_ATTRIB:
181 {
182 unsigned int hwin;
183
184 switch (reg->index) {
185 case NVS_FR_POSITION : hwin = NV30_FP_OP_INPUT_SRC_POSITION; break;
186 case NVS_FR_COL0 : hwin = NV30_FP_OP_INPUT_SRC_COL0; break;
187 case NVS_FR_COL1 : hwin = NV30_FP_OP_INPUT_SRC_COL1; break;
188 case NVS_FR_FOGCOORD : hwin = NV30_FP_OP_INPUT_SRC_FOGC; break;
189 case NVS_FR_TEXCOORD0: hwin = NV30_FP_OP_INPUT_SRC_TC(0); break;
190 case NVS_FR_TEXCOORD1: hwin = NV30_FP_OP_INPUT_SRC_TC(1); break;
191 case NVS_FR_TEXCOORD2: hwin = NV30_FP_OP_INPUT_SRC_TC(2); break;
192 case NVS_FR_TEXCOORD3: hwin = NV30_FP_OP_INPUT_SRC_TC(3); break;
193 case NVS_FR_TEXCOORD4: hwin = NV30_FP_OP_INPUT_SRC_TC(4); break;
194 case NVS_FR_TEXCOORD5: hwin = NV30_FP_OP_INPUT_SRC_TC(5); break;
195 case NVS_FR_TEXCOORD6: hwin = NV30_FP_OP_INPUT_SRC_TC(6); break;
196 case NVS_FR_TEXCOORD7: hwin = NV30_FP_OP_INPUT_SRC_TC(7); break;
197 default:
198 WARN_ONCE("unknown fp input %d\n", reg->index);
199 hwin = NV30_FP_OP_INPUT_SRC_COL0;
200 break;
201 }
202 shader->inst[0] &= ~NV30_FP_OP_INPUT_SRC_MASK;
203 shader->inst[0] |= (hwin << NV30_FP_OP_INPUT_SRC_SHIFT);
204 hwsrc |= (hwin << NV30_FP_REG_SRC_SHIFT);
205 }
206 hwsrc |= (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT);
207 break;
208 case NVS_FILE_CONST:
209 /* consts are inlined after the inst */
210 hwsrc |= (NV30_FP_REG_TYPE_CONST << NV30_FP_REG_TYPE_SHIFT);
211 break;
212 default:
213 assert(0);
214 break;
215 }
216
217 if (reg->negate)
218 hwsrc |= NV30_FP_REG_NEGATE;
219 if (reg->abs)
220 shader->inst[1] |= (1 << (29+pos));
221 hwsrc |= (reg->swizzle[NVS_SWZ_X] << NV30_FP_REG_SWZ_X_SHIFT);
222 hwsrc |= (reg->swizzle[NVS_SWZ_Y] << NV30_FP_REG_SWZ_Y_SHIFT);
223 hwsrc |= (reg->swizzle[NVS_SWZ_Z] << NV30_FP_REG_SWZ_Z_SHIFT);
224 hwsrc |= (reg->swizzle[NVS_SWZ_W] << NV30_FP_REG_SWZ_W_SHIFT);
225
226 shader->inst[pos+1] &= ~NV30_FP_REG_ALL_MASK;
227 shader->inst[pos+1] |= hwsrc;
228 }
229
230 static void
231 NV30FPSetTexImageUnit(nvsFunc *shader, int unit)
232 {
233 shader->inst[0] &= ~NV30_FP_OP_TEX_UNIT_SHIFT;
234 shader->inst[0] |= (unit << NV30_FP_OP_TEX_UNIT_SHIFT);
235 }
236
237 static void
238 NV30FPSetSaturate(nvsFunc *shader)
239 {
240 shader->inst[0] |= NV30_FP_OP_OUT_SAT;
241 }
242
243 static void
244 NV30FPInitInstruction(nvsFunc *shader)
245 {
246 unsigned int hwsrc;
247
248 shader->inst[0] = 0;
249
250 hwsrc = (NV30_FP_REG_TYPE_INPUT << NV30_FP_REG_TYPE_SHIFT) |
251 (NVS_SWZ_X << NV30_FP_REG_SWZ_X_SHIFT) |
252 (NVS_SWZ_Y << NV30_FP_REG_SWZ_Y_SHIFT) |
253 (NVS_SWZ_Z << NV30_FP_REG_SWZ_Z_SHIFT) |
254 (NVS_SWZ_W << NV30_FP_REG_SWZ_W_SHIFT);
255 shader->inst[1] = hwsrc;
256 shader->inst[2] = hwsrc;
257 shader->inst[3] = hwsrc;
258 }
259
260 static void
261 NV30FPSetLastInst(nvsFunc *shader)
262 {
263 shader->inst[0] |= 1;
264 }
265
266 /*******************************************************************************
267 * Disassembly helpers
268 */
269 static struct _op_xlat *
270 NV30FPGetOPTXRec(nvsFunc * shader, int merged)
271 {
272 int op;
273
274 op = shader->GetOpcodeHW(shader, 0);
275 if (op > NVFP_TX_AOP_COUNT)
276 return NULL;
277 if (NVFP_TX_AOP[op].SOP == NVS_OP_UNKNOWN)
278 return NULL;
279 return &NVFP_TX_AOP[op];
280 }
281
282 static int
283 NV30FPHasMergedInst(nvsFunc * shader)
284 {
285 return 0;
286 }
287
288 static int
289 NV30FPIsLastInst(nvsFunc * shader)
290 {
291 return ((shader->inst[0] & NV30_FP_OP_PROGRAM_END) ? 1 : 0);
292 }
293
294 static int
295 NV30FPGetOffsetNext(nvsFunc * shader)
296 {
297 int i;
298
299 for (i = 0; i < 3; i++)
300 if (shader->GetSourceFile(shader, 0, i) == NVS_FILE_CONST)
301 return 8;
302 return 4;
303 }
304
305 static nvsOpcode
306 NV30FPGetOpcode(nvsFunc * shader, int merged)
307 {
308 struct _op_xlat *opr;
309
310 opr = shader->GetOPTXRec(shader, merged);
311 if (!opr)
312 return NVS_OP_UNKNOWN;
313
314 return opr->SOP;
315 }
316
317 static unsigned int
318 NV30FPGetOpcodeHW(nvsFunc * shader, int slot)
319 {
320 int op;
321
322 op = (shader->inst[0] & NV30_FP_OP_OPCODE_MASK) >> NV30_FP_OP_OPCODE_SHIFT;
323
324 return op;
325 }
326
327 static nvsRegFile
328 NV30FPGetDestFile(nvsFunc * shader, int merged)
329 {
330 /* Result regs overlap temporary regs */
331 return NVS_FILE_TEMP;
332 }
333
334 static unsigned int
335 NV30FPGetDestID(nvsFunc * shader, int merged)
336 {
337 int id;
338
339 switch (shader->GetDestFile(shader, merged)) {
340 case NVS_FILE_TEMP:
341 id = ((shader->inst[0] & NV30_FP_OP_OUT_REG_MASK)
342 >> NV30_FP_OP_OUT_REG_SHIFT);
343 return id;
344 default:
345 return -1;
346 }
347 }
348
349 static unsigned int
350 NV30FPGetDestMask(nvsFunc * shader, int merged)
351 {
352 unsigned int mask = 0;
353
354 if (shader->inst[0] & NV30_FP_OP_OUT_X) mask |= SMASK_X;
355 if (shader->inst[0] & NV30_FP_OP_OUT_Y) mask |= SMASK_Y;
356 if (shader->inst[0] & NV30_FP_OP_OUT_Z) mask |= SMASK_Z;
357 if (shader->inst[0] & NV30_FP_OP_OUT_W) mask |= SMASK_W;
358
359 return mask;
360 }
361
362 static unsigned int
363 NV30FPGetSourceHW(nvsFunc * shader, int merged, int pos)
364 {
365 struct _op_xlat *opr;
366
367 opr = shader->GetOPTXRec(shader, merged);
368 if (!opr || opr->srcpos[pos] == -1)
369 return -1;
370
371 return shader->inst[opr->srcpos[pos] + 1];
372 }
373
374 static nvsRegFile
375 NV30FPGetSourceFile(nvsFunc * shader, int merged, int pos)
376 {
377 unsigned int src;
378 struct _op_xlat *opr;
379 int file;
380
381 opr = shader->GetOPTXRec(shader, merged);
382 if (!opr || opr->srcpos[pos] == -1)
383 return NVS_FILE_UNKNOWN;
384
385 switch (opr->srcpos[pos]) {
386 case SPOS_ADDRESS: return NVS_FILE_ADDRESS;
387 default:
388 src = shader->GetSourceHW(shader, merged, pos);
389 file = (src & NV30_FP_REG_TYPE_MASK) >> NV30_FP_REG_TYPE_SHIFT;
390
391 switch (file) {
392 case NV30_FP_REG_TYPE_TEMP : return NVS_FILE_TEMP;
393 case NV30_FP_REG_TYPE_INPUT: return NVS_FILE_ATTRIB;
394 case NV30_FP_REG_TYPE_CONST: return NVS_FILE_CONST;
395 default:
396 return NVS_FILE_UNKNOWN;
397 }
398 }
399 }
400
401 static int
402 NV30FPGetSourceID(nvsFunc * shader, int merged, int pos)
403 {
404 switch (shader->GetSourceFile(shader, merged, pos)) {
405 case NVS_FILE_ATTRIB:
406 switch ((shader->inst[0] & NV30_FP_OP_INPUT_SRC_MASK)
407 >> NV30_FP_OP_INPUT_SRC_SHIFT) {
408 case NV30_FP_OP_INPUT_SRC_POSITION: return NVS_FR_POSITION;
409 case NV30_FP_OP_INPUT_SRC_COL0 : return NVS_FR_COL0;
410 case NV30_FP_OP_INPUT_SRC_COL1 : return NVS_FR_COL1;
411 case NV30_FP_OP_INPUT_SRC_FOGC : return NVS_FR_FOGCOORD;
412 case NV30_FP_OP_INPUT_SRC_TC(0) : return NVS_FR_TEXCOORD0;
413 case NV30_FP_OP_INPUT_SRC_TC(1) : return NVS_FR_TEXCOORD1;
414 case NV30_FP_OP_INPUT_SRC_TC(2) : return NVS_FR_TEXCOORD2;
415 case NV30_FP_OP_INPUT_SRC_TC(3) : return NVS_FR_TEXCOORD3;
416 case NV30_FP_OP_INPUT_SRC_TC(4) : return NVS_FR_TEXCOORD4;
417 case NV30_FP_OP_INPUT_SRC_TC(5) : return NVS_FR_TEXCOORD5;
418 case NV30_FP_OP_INPUT_SRC_TC(6) : return NVS_FR_TEXCOORD6;
419 case NV30_FP_OP_INPUT_SRC_TC(7) : return NVS_FR_TEXCOORD7;
420 default:
421 return -1;
422 }
423 break;
424 case NVS_FILE_TEMP:
425 {
426 unsigned int src;
427
428 src = shader->GetSourceHW(shader, merged, pos);
429 return ((src & NV30_FP_REG_SRC_MASK) >> NV30_FP_REG_SRC_SHIFT);
430 }
431 case NVS_FILE_CONST: /* inlined into fragprog */
432 default:
433 return -1;
434 }
435 }
436
437 static int
438 NV30FPGetTexImageUnit(nvsFunc *shader)
439 {
440 return ((shader->inst[0] & NV30_FP_OP_TEX_UNIT_MASK)
441 >> NV30_FP_OP_TEX_UNIT_SHIFT);
442 }
443
444 static int
445 NV30FPGetSourceNegate(nvsFunc * shader, int merged, int pos)
446 {
447 unsigned int src;
448
449 src = shader->GetSourceHW(shader, merged, pos);
450
451 if (src == -1)
452 return -1;
453 return ((src & NV30_FP_REG_NEGATE) ? 1 : 0);
454 }
455
456 static int
457 NV30FPGetSourceAbs(nvsFunc * shader, int merged, int pos)
458 {
459 struct _op_xlat *opr;
460 static unsigned int abspos[3] = {
461 NV30_FP_OP_OUT_ABS,
462 (1 << 30), /* guess */
463 (1 << 31) /* guess */
464 };
465
466 opr = shader->GetOPTXRec(shader, merged);
467 if (!opr || opr->srcpos[pos] == -1)
468 return -1;
469
470 return ((shader->inst[1] & abspos[opr->srcpos[pos]]) ? 1 : 0);
471 }
472
473 nvsSwzComp NV30FP_TX_SWIZZLE[4] = {NVS_SWZ_X, NVS_SWZ_Y, NVS_SWZ_Z, NVS_SWZ_W };
474
475 static void
476 NV30FPTXSwizzle(int hwswz, nvsSwzComp *swz)
477 {
478 swz[NVS_SWZ_W] = NV30FP_TX_SWIZZLE[(hwswz & 0xC0) >> 6];
479 swz[NVS_SWZ_Z] = NV30FP_TX_SWIZZLE[(hwswz & 0x30) >> 4];
480 swz[NVS_SWZ_Y] = NV30FP_TX_SWIZZLE[(hwswz & 0x0C) >> 2];
481 swz[NVS_SWZ_X] = NV30FP_TX_SWIZZLE[(hwswz & 0x03) >> 0];
482 }
483
484 static void
485 NV30FPGetSourceSwizzle(nvsFunc * shader, int merged, int pos, nvsSwzComp *swz)
486 {
487 unsigned int src;
488 int swzbits;
489
490 src = shader->GetSourceHW(shader, merged, pos);
491 swzbits = (src & NV30_FP_REG_SWZ_ALL_MASK) >> NV30_FP_REG_SWZ_ALL_SHIFT;
492 NV30FPTXSwizzle(swzbits, swz);
493 }
494
495 static int
496 NV30FPGetSourceIndexed(nvsFunc * shader, int merged, int pos)
497 {
498 switch (shader->GetSourceFile(shader, merged, pos)) {
499 case NVS_FILE_ATTRIB:
500 return ((shader->inst[3] & NV30_FP_OP_INDEX_INPUT) ? 1 : 0);
501 default:
502 return 0;
503 }
504 }
505
506 static void
507 NV30FPGetSourceConstVal(nvsFunc * shader, int merged, int pos, float *val)
508 {
509 val[0] = *(float *) &(shader->inst[4]);
510 val[1] = *(float *) &(shader->inst[5]);
511 val[2] = *(float *) &(shader->inst[6]);
512 val[3] = *(float *) &(shader->inst[7]);
513 }
514
515 static int
516 NV30FPGetSourceScale(nvsFunc * shader, int merged, int pos)
517 {
518 /*FIXME: is this per-source, only for a specific source, or all sources??*/
519 return (1 << ((shader->inst[2] & NV30_FP_OP_SRC_SCALE_MASK)
520 >> NV30_FP_OP_SRC_SCALE_SHIFT));
521 }
522
523 static int
524 NV30FPGetAddressRegID(nvsFunc * shader)
525 {
526 return 0;
527 }
528
529 static nvsSwzComp
530 NV30FPGetAddressRegSwizzle(nvsFunc * shader)
531 {
532 return NVS_SWZ_X;
533 }
534
535 static int
536 NV30FPSupportsConditional(nvsFunc * shader)
537 {
538 /*FIXME: Is this true of all ops? */
539 return 1;
540 }
541
542 static int
543 NV30FPGetConditionUpdate(nvsFunc * shader)
544 {
545 return ((shader->inst[0] & NV30_FP_OP_COND_WRITE_ENABLE) ? 1 : 0);
546 }
547
548 static int
549 NV30FPGetConditionTest(nvsFunc * shader)
550 {
551 /*FIXME: always? */
552 return 1;
553 }
554
555 static nvsCond
556 NV30FPGetCondition(nvsFunc * shader)
557 {
558 int cond;
559
560 cond = ((shader->inst[1] & NV30_FP_OP_COND_MASK)
561 >> NV30_FP_OP_COND_SHIFT);
562
563 switch (cond) {
564 case NV30_FP_OP_COND_FL: return NVS_COND_FL;
565 case NV30_FP_OP_COND_LT: return NVS_COND_LT;
566 case NV30_FP_OP_COND_EQ: return NVS_COND_EQ;
567 case NV30_FP_OP_COND_LE: return NVS_COND_LE;
568 case NV30_FP_OP_COND_GT: return NVS_COND_GT;
569 case NV30_FP_OP_COND_NE: return NVS_COND_NE;
570 case NV30_FP_OP_COND_GE: return NVS_COND_GE;
571 case NV30_FP_OP_COND_TR: return NVS_COND_TR;
572 default:
573 return NVS_COND_UNKNOWN;
574 }
575 }
576
577 static void
578 NV30FPGetCondRegSwizzle(nvsFunc * shader, nvsSwzComp *swz)
579 {
580 int swzbits;
581
582 swzbits = (shader->inst[1] & NV30_FP_OP_COND_SWZ_ALL_MASK)
583 >> NV30_FP_OP_COND_SWZ_ALL_SHIFT;
584 NV30FPTXSwizzle(swzbits, swz);
585 }
586
587 static int
588 NV30FPGetCondRegID(nvsFunc * shader)
589 {
590 return 0;
591 }
592
593 static nvsPrecision
594 NV30FPGetPrecision(nvsFunc * shader)
595 {
596 int p;
597
598 p = (shader->inst[0] & NV30_FP_OP_PRECISION_MASK)
599 >> NV30_FP_OP_PRECISION_SHIFT;
600
601 switch (p) {
602 case NV30_FP_PRECISION_FP32: return NVS_PREC_FLOAT32;
603 case NV30_FP_PRECISION_FP16: return NVS_PREC_FLOAT16;
604 case NV30_FP_PRECISION_FX12: return NVS_PREC_FIXED12;
605 default:
606 return NVS_PREC_UNKNOWN;
607 }
608 }
609
610 static int
611 NV30FPGetSaturate(nvsFunc * shader)
612 {
613 return ((shader->inst[0] & NV30_FP_OP_OUT_SAT) ? 1 : 0);
614 }
615
616 /*******************************************************************************
617 * Init
618 */
619 void
620 NV30FPInitShaderFuncs(nvsFunc * shader)
621 {
622 /* These are probably bogus, I made them up... */
623 shader->MaxInst = 1024;
624 shader->MaxAttrib = 16;
625 shader->MaxTemp = 32;
626 shader->MaxAddress = 1;
627 shader->MaxConst = 256;
628 shader->caps = SCAP_SRC_ABS;
629
630 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MOV, NVS_OP_MOV, 0, -1, -1);
631 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MUL, NVS_OP_MUL, 0, 1, -1);
632 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_ADD, NVS_OP_ADD, 0, 1, -1);
633 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAD, NVS_OP_MAD, 0, 1, 2);
634 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP3, NVS_OP_DP3, 0, 1, -1);
635 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DP4, NVS_OP_DP4, 0, 1, -1);
636 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DST, NVS_OP_DST, 0, 1, -1);
637 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MIN, NVS_OP_MIN, 0, 1, -1);
638 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_MAX, NVS_OP_MAX, 0, 1, -1);
639 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLT, NVS_OP_SLT, 0, 1, -1);
640 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGE, NVS_OP_SGE, 0, 1, -1);
641 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FRC, NVS_OP_FRC, 0, -1, -1);
642 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_FLR, NVS_OP_FLR, 0, -1, -1);
643 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TEX, NVS_OP_TEX, 0, -1, -1);
644 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXD, NVS_OP_TXD, 0, 1, 2);
645 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXP, NVS_OP_TXP, 0, -1, -1);
646 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_TXB, NVS_OP_TXB, 0, -1, -1);
647 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SEQ, NVS_OP_SEQ, 0, 1, -1);
648 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SGT, NVS_OP_SGT, 0, 1, -1);
649 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SLE, NVS_OP_SLE, 0, 1, -1);
650 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SNE, NVS_OP_SNE, 0, 1, -1);
651 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RCP, NVS_OP_RCP, 0, -1, -1);
652 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LG2, NVS_OP_LG2, 0, -1, -1);
653 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_EX2, NVS_OP_EX2, 0, -1, -1);
654 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_COS, NVS_OP_COS, 0, -1, -1);
655 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_SIN, NVS_OP_SIN, 0, -1, -1);
656 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_NOP, NVS_OP_NOP, -1, -1, -1);
657 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDX, NVS_OP_DDX, 0, -1, -1);
658 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_DDY, NVS_OP_DDY, 0, -1, -1);
659 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_KIL, NVS_OP_KIL, -1, -1, -1);
660 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4B, NVS_OP_PK4B, 0, -1, -1);
661 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4B, NVS_OP_UP4B, 0, -1, -1);
662 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2H, NVS_OP_PK2H, 0, -1, -1);
663 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2H, NVS_OP_UP2H, 0, -1, -1);
664 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK4UB, NVS_OP_PK4UB, 0, -1, -1);
665 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP4UB, NVS_OP_UP4UB, 0, -1, -1);
666 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_PK2US, NVS_OP_PK2US, 0, -1, -1);
667 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_UP2US, NVS_OP_UP2US, 0, -1, -1);
668 /*FIXME: Haven't confirmed the source positions for the below opcodes */
669 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LIT, NVS_OP_LIT, 0, -1, -1);
670 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_LRP, NVS_OP_LRP, 0, 1, 2);
671 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_POW, NVS_OP_POW, 0, 1, -1);
672 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RSQ, NVS_OP_RSQ, 0, -1, -1);
673 MOD_OPCODE(NVFP_TX_AOP, NV30_FP_OP_OPCODE_RFL, NVS_OP_RFL, 0, 1, -1);
674
675 shader->GetOPTXRec = NV30FPGetOPTXRec;
676 shader->GetOPTXFromSOP = NV30FPGetOPTXFromSOP;
677
678 shader->UploadToHW = NV30FPUploadToHW;
679 shader->UpdateConst = NV30FPUpdateConst;
680
681 shader->InitInstruction = NV30FPInitInstruction;
682 shader->SupportsOpcode = NV30FPSupportsOpcode;
683 shader->SetOpcode = NV30FPSetOpcode;
684 shader->SetCCUpdate = NV30FPSetCCUpdate;
685 shader->SetCondition = NV30FPSetCondition;
686 shader->SetResult = NV30FPSetResult;
687 shader->SetSource = NV30FPSetSource;
688 shader->SetTexImageUnit = NV30FPSetTexImageUnit;
689 shader->SetSaturate = NV30FPSetSaturate;
690 shader->SetLastInst = NV30FPSetLastInst;
691
692 shader->HasMergedInst = NV30FPHasMergedInst;
693 shader->IsLastInst = NV30FPIsLastInst;
694 shader->GetOffsetNext = NV30FPGetOffsetNext;
695 shader->GetOpcode = NV30FPGetOpcode;
696 shader->GetOpcodeHW = NV30FPGetOpcodeHW;
697 shader->GetDestFile = NV30FPGetDestFile;
698 shader->GetDestID = NV30FPGetDestID;
699 shader->GetDestMask = NV30FPGetDestMask;
700 shader->GetSourceHW = NV30FPGetSourceHW;
701 shader->GetSourceFile = NV30FPGetSourceFile;
702 shader->GetSourceID = NV30FPGetSourceID;
703 shader->GetTexImageUnit = NV30FPGetTexImageUnit;
704 shader->GetSourceNegate = NV30FPGetSourceNegate;
705 shader->GetSourceAbs = NV30FPGetSourceAbs;
706 shader->GetSourceSwizzle = NV30FPGetSourceSwizzle;
707 shader->GetSourceIndexed = NV30FPGetSourceIndexed;
708 shader->GetSourceConstVal = NV30FPGetSourceConstVal;
709 shader->GetSourceScale = NV30FPGetSourceScale;
710 shader->GetRelAddressRegID = NV30FPGetAddressRegID;
711 shader->GetRelAddressSwizzle = NV30FPGetAddressRegSwizzle;
712 shader->GetPrecision = NV30FPGetPrecision;
713 shader->GetSaturate = NV30FPGetSaturate;
714 shader->SupportsConditional = NV30FPSupportsConditional;
715 shader->GetConditionUpdate = NV30FPGetConditionUpdate;
716 shader->GetConditionTest = NV30FPGetConditionTest;
717 shader->GetCondition = NV30FPGetCondition;
718 shader->GetCondRegSwizzle = NV30FPGetCondRegSwizzle;
719 shader->GetCondRegID = NV30FPGetCondRegID;
720 }