r300-gallium: r500 surface_copy fragment shader.
[mesa.git] / src / gallium / drivers / r300 / r300_state_shader.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
22
23 #include "r300_state_shader.h"
24
25 static void r300_copy_passthrough_shader(struct r300_fragment_shader* fs)
26 {
27 struct r300_fragment_shader* pt = &r300_passthrough_fragment_shader;
28 fs->shader.stack_size = pt->shader.stack_size;
29 fs->alu_instruction_count = pt->alu_instruction_count;
30 fs->tex_instruction_count = pt->tex_instruction_count;
31 fs->indirections = pt->indirections;
32 fs->instructions[0] = pt->instructions[0];
33 }
34
35 static void r500_copy_passthrough_shader(struct r500_fragment_shader* fs)
36 {
37 struct r500_fragment_shader* pt = &r500_passthrough_fragment_shader;
38 fs->shader.stack_size = pt->shader.stack_size;
39 fs->instruction_count = pt->instruction_count;
40 fs->instructions[0] = pt->instructions[0];
41 }
42
43 static void r300_fs_declare(struct r300_fs_asm* assembler,
44 struct tgsi_full_declaration* decl)
45 {
46 switch (decl->Declaration.File) {
47 case TGSI_FILE_INPUT:
48 switch (decl->Semantic.SemanticName) {
49 case TGSI_SEMANTIC_COLOR:
50 assembler->color_count++;
51 break;
52 case TGSI_SEMANTIC_GENERIC:
53 assembler->tex_count++;
54 break;
55 default:
56 debug_printf("r300: fs: Bad semantic declaration %d\n",
57 decl->Semantic.SemanticName);
58 break;
59 }
60 break;
61 case TGSI_FILE_OUTPUT:
62 case TGSI_FILE_CONSTANT:
63 break;
64 case TGSI_FILE_TEMPORARY:
65 assembler->temp_count++;
66 break;
67 default:
68 debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File);
69 break;
70 }
71
72 assembler->temp_offset = assembler->color_count + assembler->tex_count;
73 }
74
75 static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler,
76 struct tgsi_src_register* src)
77 {
78 switch (src->File) {
79 case TGSI_FILE_NULL:
80 return 0;
81 case TGSI_FILE_INPUT:
82 /* XXX may be wrong */
83 return src->Index;
84 break;
85 case TGSI_FILE_TEMPORARY:
86 return src->Index + assembler->temp_offset;
87 break;
88 case TGSI_FILE_IMMEDIATE:
89 return (src->Index + assembler->imm_offset) | (1 << 8);
90 break;
91 case TGSI_FILE_CONSTANT:
92 /* XXX magic */
93 return src->Index | (1 << 8);
94 break;
95 default:
96 debug_printf("r300: fs: Unimplemented src %d\n", src->File);
97 break;
98 }
99 return 0;
100 }
101
102 static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
103 struct tgsi_dst_register* dst)
104 {
105 switch (dst->File) {
106 case TGSI_FILE_NULL:
107 /* This happens during KIL instructions. */
108 return 0;
109 break;
110 case TGSI_FILE_OUTPUT:
111 return 0;
112 break;
113 case TGSI_FILE_TEMPORARY:
114 return dst->Index + assembler->temp_offset;
115 break;
116 default:
117 debug_printf("r300: fs: Unimplemented dst %d\n", dst->File);
118 break;
119 }
120 return 0;
121 }
122
123 static INLINE unsigned r500_fix_swiz(unsigned s)
124 {
125 /* For historical reasons, the swizzle values x, y, z, w, and 0 are
126 * equivalent to the actual machine code, but 1 is not. Thus, we just
127 * adjust it a bit... */
128 if (s == TGSI_EXTSWIZZLE_ONE) {
129 return R500_SWIZZLE_ONE;
130 } else {
131 return s;
132 }
133 }
134
135 static uint32_t r500_rgba_swiz(struct tgsi_full_src_register* reg)
136 {
137 if (reg->SrcRegister.Extended) {
138 return r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
139 (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
140 (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
141 (r500_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
142 } else {
143 return reg->SrcRegister.SwizzleX |
144 (reg->SrcRegister.SwizzleY << 3) |
145 (reg->SrcRegister.SwizzleZ << 6) |
146 (reg->SrcRegister.SwizzleW << 9);
147 }
148 }
149
150 static uint32_t r500_strq_swiz(struct tgsi_full_src_register* reg)
151 {
152 return reg->SrcRegister.SwizzleX |
153 (reg->SrcRegister.SwizzleY << 2) |
154 (reg->SrcRegister.SwizzleZ << 4) |
155 (reg->SrcRegister.SwizzleW << 6);
156 }
157
158 static INLINE uint32_t r500_rgb_swiz(struct tgsi_full_src_register* reg)
159 {
160 /* Only the first 9 bits... */
161 return (r500_rgba_swiz(reg) & 0x1ff) |
162 (reg->SrcRegister.Negate ? (1 << 9) : 0) |
163 (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
164 }
165
166 static INLINE uint32_t r500_alpha_swiz(struct tgsi_full_src_register* reg)
167 {
168 /* Only the last 3 bits... */
169 return (r500_rgba_swiz(reg) >> 9) |
170 (reg->SrcRegister.Negate ? (1 << 9) : 0) |
171 (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
172 }
173
174 static INLINE uint32_t r300_rgb_op(unsigned op)
175 {
176 switch (op) {
177 case TGSI_OPCODE_MOV:
178 return R300_ALU_OUTC_CMP;
179 default:
180 return 0;
181 }
182 }
183
184 static INLINE uint32_t r300_alpha_op(unsigned op)
185 {
186 switch (op) {
187 case TGSI_OPCODE_MOV:
188 return R300_ALU_OUTA_CMP;
189 default:
190 return 0;
191 }
192 }
193
194 static INLINE uint32_t r500_rgba_op(unsigned op)
195 {
196 switch (op) {
197 case TGSI_OPCODE_EX2:
198 case TGSI_OPCODE_LG2:
199 case TGSI_OPCODE_RCP:
200 case TGSI_OPCODE_RSQ:
201 return R500_ALU_RGBA_OP_SOP;
202 case TGSI_OPCODE_FRC:
203 return R500_ALU_RGBA_OP_FRC;
204 case TGSI_OPCODE_DP3:
205 return R500_ALU_RGBA_OP_DP3;
206 case TGSI_OPCODE_DP4:
207 case TGSI_OPCODE_DPH:
208 return R500_ALU_RGBA_OP_DP4;
209 case TGSI_OPCODE_ABS:
210 case TGSI_OPCODE_CMP:
211 case TGSI_OPCODE_MOV:
212 case TGSI_OPCODE_SWZ:
213 return R500_ALU_RGBA_OP_CMP;
214 case TGSI_OPCODE_ADD:
215 case TGSI_OPCODE_MAD:
216 case TGSI_OPCODE_MUL:
217 case TGSI_OPCODE_SUB:
218 return R500_ALU_RGBA_OP_MAD;
219 default:
220 return 0;
221 }
222 }
223
224 static INLINE uint32_t r500_alpha_op(unsigned op)
225 {
226 switch (op) {
227 case TGSI_OPCODE_EX2:
228 return R500_ALPHA_OP_EX2;
229 case TGSI_OPCODE_LG2:
230 return R500_ALPHA_OP_LN2;
231 case TGSI_OPCODE_RCP:
232 return R500_ALPHA_OP_RCP;
233 case TGSI_OPCODE_RSQ:
234 return R500_ALPHA_OP_RSQ;
235 case TGSI_OPCODE_FRC:
236 return R500_ALPHA_OP_FRC;
237 case TGSI_OPCODE_DP3:
238 case TGSI_OPCODE_DP4:
239 case TGSI_OPCODE_DPH:
240 return R500_ALPHA_OP_DP;
241 case TGSI_OPCODE_ABS:
242 case TGSI_OPCODE_CMP:
243 case TGSI_OPCODE_MOV:
244 case TGSI_OPCODE_SWZ:
245 return R500_ALPHA_OP_CMP;
246 case TGSI_OPCODE_ADD:
247 case TGSI_OPCODE_MAD:
248 case TGSI_OPCODE_MUL:
249 case TGSI_OPCODE_SUB:
250 return R500_ALPHA_OP_MAD;
251 default:
252 return 0;
253 }
254 }
255
256 static INLINE uint32_t r500_tex_op(unsigned op)
257 {
258 switch (op) {
259 case TGSI_OPCODE_KIL:
260 return R500_TEX_INST_TEXKILL;
261 case TGSI_OPCODE_TEX:
262 return R500_TEX_INST_LD;
263 case TGSI_OPCODE_TXB:
264 return R500_TEX_INST_LODBIAS;
265 case TGSI_OPCODE_TXP:
266 return R500_TEX_INST_PROJ;
267 default:
268 return 0;
269 }
270 }
271
272 static INLINE void r300_emit_maths(struct r300_fragment_shader* fs,
273 struct r300_fs_asm* assembler,
274 struct tgsi_full_src_register* src,
275 struct tgsi_full_dst_register* dst,
276 unsigned op,
277 unsigned count)
278 {
279 int i = fs->alu_instruction_count;
280
281 fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
282 R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
283 R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
284 r300_rgb_op(op);
285 fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
286 R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
287 fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
288 R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
289 R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
290 r300_alpha_op(op);
291 fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
292 R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
293
294 fs->alu_instruction_count++;
295 }
296
297 /* Setup an ALU operation. */
298 static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,
299 struct r300_fs_asm* assembler,
300 struct tgsi_full_dst_register* dst)
301 {
302 int i = fs->instruction_count;
303
304 if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
305 fs->instructions[i].inst0 = R500_INST_TYPE_OUT |
306 R500_ALU_OMASK(dst->DstRegister.WriteMask);
307 } else {
308 fs->instructions[i].inst0 = R500_INST_TYPE_ALU |
309 R500_ALU_WMASK(dst->DstRegister.WriteMask);
310 }
311
312 fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT;
313
314 fs->instructions[i].inst4 =
315 R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
316 fs->instructions[i].inst5 =
317 R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
318 }
319
320 static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
321 struct r300_fs_asm* assembler,
322 struct tgsi_full_src_register* src,
323 struct tgsi_full_dst_register* dst,
324 unsigned op,
325 unsigned count)
326 {
327 int i = fs->instruction_count;
328
329 r500_emit_alu(fs, assembler, dst);
330
331 switch (count) {
332 case 3:
333 fs->instructions[i].inst1 =
334 R500_RGB_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
335 fs->instructions[i].inst2 =
336 R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
337 fs->instructions[i].inst5 |=
338 R500_ALU_RGBA_SEL_C_SRC2 |
339 R500_SWIZ_RGBA_C(r500_rgb_swiz(&src[2])) |
340 R500_ALU_RGBA_ALPHA_SEL_C_SRC2 |
341 R500_SWIZ_ALPHA_C(r500_alpha_swiz(&src[2]));
342 case 2:
343 fs->instructions[i].inst1 |=
344 R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
345 fs->instructions[i].inst2 |=
346 R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
347 fs->instructions[i].inst3 =
348 R500_ALU_RGB_SEL_B_SRC1 |
349 R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1]));
350 fs->instructions[i].inst4 |=
351 R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])) |
352 R500_ALPHA_SEL_B_SRC1;
353 case 1:
354 case 0:
355 default:
356 fs->instructions[i].inst1 |=
357 R500_RGB_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
358 fs->instructions[i].inst2 |=
359 R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
360 fs->instructions[i].inst3 |=
361 R500_ALU_RGB_SEL_A_SRC0 |
362 R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0]));
363 fs->instructions[i].inst4 |=
364 R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])) |
365 R500_ALPHA_SEL_A_SRC0;
366 break;
367 }
368
369 fs->instructions[i].inst4 |= r500_alpha_op(op);
370 fs->instructions[i].inst5 |= r500_rgba_op(op);
371
372 fs->instruction_count++;
373 }
374
375 static INLINE void r500_emit_tex(struct r500_fragment_shader* fs,
376 struct r300_fs_asm* assembler,
377 struct tgsi_full_src_register* src,
378 struct tgsi_full_dst_register* dst,
379 uint32_t op)
380 {
381 int i = fs->instruction_count;
382
383 fs->instructions[i].inst0 = R500_INST_TYPE_TEX |
384 R500_TEX_WMASK(dst->DstRegister.WriteMask) |
385 R500_INST_TEX_SEM_WAIT;
386 fs->instructions[i].inst1 = R500_TEX_ID(0) |
387 R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED |
388 r500_tex_op(op);
389 fs->instructions[i].inst2 =
390 R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
391 R500_SWIZ_TEX_STRQ(r500_strq_swiz(src)) |
392 R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
393 R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
394 R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
395
396 if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
397 fs->instructions[i].inst2 |=
398 R500_TEX_DST_ADDR(assembler->temp_count +
399 assembler->temp_offset);
400
401 fs->instruction_count++;
402
403 /* Setup and emit a MOV. */
404 src[0].SrcRegister.Index = assembler->temp_count;
405 src[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
406
407 src[1] = src[0];
408 src[2] = r500_constant_zero;
409 r500_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
410 } else {
411 fs->instruction_count++;
412 }
413 }
414
415 static void r300_fs_instruction(struct r300_fragment_shader* fs,
416 struct r300_fs_asm* assembler,
417 struct tgsi_full_instruction* inst)
418 {
419 switch (inst->Instruction.Opcode) {
420 case TGSI_OPCODE_MOV:
421 /* src0 -> src1 and src2 forced to zero */
422 inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
423 inst->FullSrcRegisters[2] = r500_constant_zero;
424 r300_emit_maths(fs, assembler, inst->FullSrcRegisters,
425 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
426 break;
427 case TGSI_OPCODE_END:
428 break;
429 default:
430 debug_printf("r300: fs: Bad opcode %d\n",
431 inst->Instruction.Opcode);
432 break;
433 }
434 }
435
436 static void r500_fs_instruction(struct r500_fragment_shader* fs,
437 struct r300_fs_asm* assembler,
438 struct tgsi_full_instruction* inst)
439 {
440 /* Switch between opcodes. When possible, prefer using the official
441 * AMD/ATI names for opcodes, please, as it facilitates using the
442 * documentation. */
443 switch (inst->Instruction.Opcode) {
444 /* The simple scalar ops. */
445 case TGSI_OPCODE_EX2:
446 case TGSI_OPCODE_LG2:
447 case TGSI_OPCODE_RCP:
448 case TGSI_OPCODE_RSQ:
449 /* Copy red swizzle to alpha for src0 */
450 inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
451 inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
452 inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
453 inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
454 /* Fall through */
455 case TGSI_OPCODE_FRC:
456 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
457 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);
458 break;
459
460 /* The dot products. */
461 case TGSI_OPCODE_DPH:
462 /* Set alpha swizzle to one for src0 */
463 if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
464 inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
465 inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
466 inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
467 inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
468 inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
469 inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
470 inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
471 }
472 inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
473 TGSI_EXTSWIZZLE_ONE;
474 /* Fall through */
475 case TGSI_OPCODE_DP3:
476 case TGSI_OPCODE_DP4:
477 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
478 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2);
479 break;
480
481 /* Simple three-source operations. */
482 case TGSI_OPCODE_CMP:
483 /* Swap src0 and src2 */
484 inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2];
485 inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0];
486 inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3];
487 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
488 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
489 break;
490
491 /* The MAD variants. */
492 case TGSI_OPCODE_SUB:
493 /* Just like ADD, but flip the negation on src1 first */
494 inst->FullSrcRegisters[1].SrcRegister.Negate =
495 !inst->FullSrcRegisters[1].SrcRegister.Negate;
496 /* Fall through */
497 case TGSI_OPCODE_ADD:
498 /* Force src0 to one, move all registers over */
499 inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1];
500 inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
501 inst->FullSrcRegisters[0] = r500_constant_one;
502 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
503 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
504 break;
505 case TGSI_OPCODE_MUL:
506 /* Force our src2 to zero */
507 inst->FullSrcRegisters[2] = r500_constant_zero;
508 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
509 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
510 break;
511 case TGSI_OPCODE_MAD:
512 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
513 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
514 break;
515
516 /* The MOV variants. */
517 case TGSI_OPCODE_ABS:
518 /* Set absolute value modifiers. */
519 inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE;
520 /* Fall through */
521 case TGSI_OPCODE_MOV:
522 case TGSI_OPCODE_SWZ:
523 /* src0 -> src1 and src2 forced to zero */
524 inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
525 inst->FullSrcRegisters[2] = r500_constant_zero;
526 r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
527 &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
528 break;
529
530 /* The texture instruction set. */
531 case TGSI_OPCODE_KIL:
532 case TGSI_OPCODE_TEX:
533 case TGSI_OPCODE_TXB:
534 case TGSI_OPCODE_TXP:
535 r500_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],
536 &inst->FullDstRegisters[0], inst->Instruction.Opcode);
537 break;
538
539 /* This is the end. My only friend, the end. */
540 case TGSI_OPCODE_END:
541 break;
542 default:
543 debug_printf("r300: fs: Bad opcode %d\n",
544 inst->Instruction.Opcode);
545 break;
546 }
547
548 /* Clamp, if saturation flags are set. */
549 if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) {
550 fs->instructions[fs->instruction_count - 1].inst0 |=
551 R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
552 }
553 }
554
555 static void r300_fs_finalize(struct r3xx_fragment_shader* fs,
556 struct r300_fs_asm* assembler)
557 {
558 fs->stack_size = assembler->temp_count + assembler->temp_offset;
559 }
560
561 static void r500_fs_finalize(struct r500_fragment_shader* fs,
562 struct r300_fs_asm* assembler)
563 {
564 /* XXX should this just go with OPCODE_END? */
565 fs->instructions[fs->instruction_count - 1].inst0 |=
566 R500_INST_LAST;
567 }
568
569 void r300_translate_fragment_shader(struct r300_context* r300,
570 struct r3xx_fragment_shader* fs)
571 {
572 struct tgsi_parse_context parser;
573 int i;
574 boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
575 struct r300_constant_buffer* consts =
576 &r300->shader_constants[PIPE_SHADER_FRAGMENT];
577
578 struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
579 if (assembler == NULL) {
580 return;
581 }
582 /* Setup starting offset for immediates. */
583 assembler->imm_offset = consts->user_count;
584
585 /* Make sure we start at the beginning of the shader. */
586 if (is_r500) {
587 ((struct r500_fragment_shader*)fs)->instruction_count = 0;
588 }
589
590 tgsi_parse_init(&parser, fs->state.tokens);
591
592 while (!tgsi_parse_end_of_tokens(&parser)) {
593 tgsi_parse_token(&parser);
594
595 /* This is seriously the lamest way to create fragment programs ever.
596 * I blame TGSI. */
597 switch (parser.FullToken.Token.Type) {
598 case TGSI_TOKEN_TYPE_DECLARATION:
599 /* Allocated registers sitting at the beginning
600 * of the program. */
601 r300_fs_declare(assembler, &parser.FullToken.FullDeclaration);
602 break;
603 case TGSI_TOKEN_TYPE_IMMEDIATE:
604 debug_printf("r300: Emitting immediate to constant buffer, "
605 "position %d\n",
606 assembler->imm_offset + assembler->imm_count);
607 /* I am not amused by the length of these. */
608 for (i = 0; i < 4; i++) {
609 consts->constants[assembler->imm_offset +
610 assembler->imm_count][i] =
611 parser.FullToken.FullImmediate.u.ImmediateFloat32[i]
612 .Float;
613 }
614 assembler->imm_count++;
615 break;
616 case TGSI_TOKEN_TYPE_INSTRUCTION:
617 if (is_r500) {
618 r500_fs_instruction((struct r500_fragment_shader*)fs,
619 assembler, &parser.FullToken.FullInstruction);
620 } else {
621 r300_fs_instruction((struct r300_fragment_shader*)fs,
622 assembler, &parser.FullToken.FullInstruction);
623 }
624 break;
625 }
626 }
627
628 debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
629 assembler->tex_count, assembler->color_count,
630 assembler->tex_count + assembler->color_count);
631
632 consts->count = consts->user_count + assembler->imm_count;
633 debug_printf("r300: fs: %d total constants, "
634 "%d from user and %d from immediates\n", consts->count,
635 consts->user_count, assembler->imm_count);
636 r300_fs_finalize(fs, assembler);
637 if (is_r500) {
638 r500_fs_finalize((struct r500_fragment_shader*)fs, assembler);
639 }
640
641 tgsi_dump(fs->state.tokens);
642 /* XXX finish r300 dumper too */
643 if (is_r500) {
644 r500_fs_dump((struct r500_fragment_shader*)fs);
645 }
646
647 tgsi_parse_free(&parser);
648 FREE(assembler);
649 }