2 * Copyright (C) 2005 Ben Skeggs.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 * Fragment program compiler. Perform transformations on the intermediate
32 * representation until the program is in a form where we can translate
33 * it more or less directly into machine-readable form.
35 * \author Ben Skeggs <darktama@iinet.net.au>
36 * \author Jerome Glisse <j.glisse@gmail.com>
39 #include "main/glheader.h"
40 #include "main/macros.h"
41 #include "main/enums.h"
42 #include "shader/prog_instruction.h"
43 #include "shader/prog_parameter.h"
44 #include "shader/prog_print.h"
46 #include "r300_context.h"
47 #include "r300_fragprog.h"
48 #include "r300_fragprog_swizzle.h"
49 #include "r300_state.h"
51 #include "radeon_nqssadce.h"
52 #include "radeon_program_alu.h"
55 static void reset_srcreg(struct prog_src_register
* reg
)
57 _mesa_bzero(reg
, sizeof(*reg
));
58 reg
->Swizzle
= SWIZZLE_NOOP
;
61 static struct prog_src_register
shadow_ambient(struct gl_program
*program
, int tmu
)
63 gl_state_index fail_value_tokens
[STATE_LENGTH
] = {
64 STATE_INTERNAL
, STATE_SHADOW_AMBIENT
, 0, 0, 0
66 struct prog_src_register reg
= { 0, };
68 fail_value_tokens
[2] = tmu
;
69 reg
.File
= PROGRAM_STATE_VAR
;
70 reg
.Index
= _mesa_add_state_reference(program
->Parameters
, fail_value_tokens
);
71 reg
.Swizzle
= SWIZZLE_WWWW
;
76 * Transform TEX, TXP, TXB, and KIL instructions in the following way:
77 * - premultiply texture coordinates for RECT
78 * - extract operand swizzles
79 * - introduce a temporary register when write masks are needed
81 * \todo If/when r5xx uses the radeon_program architecture, this can probably
84 static GLboolean
transform_TEX(
85 struct radeon_transform_context
*t
,
86 struct prog_instruction
* orig_inst
, void* data
)
88 struct r300_fragment_program_compiler
*compiler
=
89 (struct r300_fragment_program_compiler
*)data
;
90 struct prog_instruction inst
= *orig_inst
;
91 struct prog_instruction
* tgt
;
92 GLboolean destredirect
= GL_FALSE
;
94 if (inst
.Opcode
!= OPCODE_TEX
&&
95 inst
.Opcode
!= OPCODE_TXB
&&
96 inst
.Opcode
!= OPCODE_TXP
&&
97 inst
.Opcode
!= OPCODE_KIL
)
100 if (inst
.Opcode
!= OPCODE_KIL
&&
101 t
->Program
->ShadowSamplers
& (1 << inst
.TexSrcUnit
)) {
102 GLuint comparefunc
= GL_NEVER
+ compiler
->fp
->state
.unit
[inst
.TexSrcUnit
].texture_compare_func
;
104 if (comparefunc
== GL_NEVER
|| comparefunc
== GL_ALWAYS
) {
105 tgt
= radeonAppendInstructions(t
->Program
, 1);
107 tgt
->Opcode
= OPCODE_MOV
;
108 tgt
->DstReg
= inst
.DstReg
;
109 if (comparefunc
== GL_ALWAYS
) {
110 tgt
->SrcReg
[0].File
= PROGRAM_BUILTIN
;
111 tgt
->SrcReg
[0].Swizzle
= SWIZZLE_1111
;
113 tgt
->SrcReg
[0] = shadow_ambient(t
->Program
, inst
.TexSrcUnit
);
118 inst
.DstReg
.File
= PROGRAM_TEMPORARY
;
119 inst
.DstReg
.Index
= radeonFindFreeTemporary(t
);
120 inst
.DstReg
.WriteMask
= WRITEMASK_XYZW
;
124 /* Hardware uses [0..1]x[0..1] range for rectangle textures
125 * instead of [0..Width]x[0..Height].
126 * Add a scaling instruction.
128 if (inst
.Opcode
!= OPCODE_KIL
&& inst
.TexSrcTarget
== TEXTURE_RECT_INDEX
) {
129 gl_state_index tokens
[STATE_LENGTH
] = {
130 STATE_INTERNAL
, STATE_R300_TEXRECT_FACTOR
, 0, 0,
134 int tempreg
= radeonFindFreeTemporary(t
);
137 tokens
[2] = inst
.TexSrcUnit
;
138 factor_index
= _mesa_add_state_reference(t
->Program
->Parameters
, tokens
);
140 tgt
= radeonAppendInstructions(t
->Program
, 1);
142 tgt
->Opcode
= OPCODE_MUL
;
143 tgt
->DstReg
.File
= PROGRAM_TEMPORARY
;
144 tgt
->DstReg
.Index
= tempreg
;
145 tgt
->SrcReg
[0] = inst
.SrcReg
[0];
146 tgt
->SrcReg
[1].File
= PROGRAM_STATE_VAR
;
147 tgt
->SrcReg
[1].Index
= factor_index
;
149 reset_srcreg(&inst
.SrcReg
[0]);
150 inst
.SrcReg
[0].File
= PROGRAM_TEMPORARY
;
151 inst
.SrcReg
[0].Index
= tempreg
;
154 if (inst
.Opcode
!= OPCODE_KIL
) {
155 if (inst
.DstReg
.File
!= PROGRAM_TEMPORARY
||
156 inst
.DstReg
.WriteMask
!= WRITEMASK_XYZW
) {
157 int tempreg
= radeonFindFreeTemporary(t
);
159 inst
.DstReg
.File
= PROGRAM_TEMPORARY
;
160 inst
.DstReg
.Index
= tempreg
;
161 inst
.DstReg
.WriteMask
= WRITEMASK_XYZW
;
162 destredirect
= GL_TRUE
;
166 if (inst
.SrcReg
[0].File
!= PROGRAM_TEMPORARY
&& inst
.SrcReg
[0].File
!= PROGRAM_INPUT
) {
167 int tmpreg
= radeonFindFreeTemporary(t
);
168 tgt
= radeonAppendInstructions(t
->Program
, 1);
169 tgt
->Opcode
= OPCODE_MOV
;
170 tgt
->DstReg
.File
= PROGRAM_TEMPORARY
;
171 tgt
->DstReg
.Index
= tmpreg
;
172 tgt
->SrcReg
[0] = inst
.SrcReg
[0];
174 reset_srcreg(&inst
.SrcReg
[0]);
175 inst
.SrcReg
[0].File
= PROGRAM_TEMPORARY
;
176 inst
.SrcReg
[0].Index
= tmpreg
;
179 tgt
= radeonAppendInstructions(t
->Program
, 1);
180 _mesa_copy_instructions(tgt
, &inst
, 1);
182 if (inst
.Opcode
!= OPCODE_KIL
&&
183 t
->Program
->ShadowSamplers
& (1 << inst
.TexSrcUnit
)) {
184 GLuint comparefunc
= GL_NEVER
+ compiler
->fp
->state
.unit
[inst
.TexSrcUnit
].texture_compare_func
;
185 GLuint depthmode
= compiler
->fp
->state
.unit
[inst
.TexSrcUnit
].depth_texture_mode
;
186 int rcptemp
= radeonFindFreeTemporary(t
);
189 tgt
= radeonAppendInstructions(t
->Program
, 3);
191 tgt
[0].Opcode
= OPCODE_RCP
;
192 tgt
[0].DstReg
.File
= PROGRAM_TEMPORARY
;
193 tgt
[0].DstReg
.Index
= rcptemp
;
194 tgt
[0].DstReg
.WriteMask
= WRITEMASK_W
;
195 tgt
[0].SrcReg
[0] = inst
.SrcReg
[0];
196 tgt
[0].SrcReg
[0].Swizzle
= SWIZZLE_WWWW
;
198 tgt
[1].Opcode
= OPCODE_MAD
;
199 tgt
[1].DstReg
= inst
.DstReg
;
200 tgt
[1].DstReg
.WriteMask
= orig_inst
->DstReg
.WriteMask
;
201 tgt
[1].SrcReg
[0] = inst
.SrcReg
[0];
202 tgt
[1].SrcReg
[0].Swizzle
= SWIZZLE_ZZZZ
;
203 tgt
[1].SrcReg
[1].File
= PROGRAM_TEMPORARY
;
204 tgt
[1].SrcReg
[1].Index
= rcptemp
;
205 tgt
[1].SrcReg
[1].Swizzle
= SWIZZLE_WWWW
;
206 tgt
[1].SrcReg
[2].File
= PROGRAM_TEMPORARY
;
207 tgt
[1].SrcReg
[2].Index
= inst
.DstReg
.Index
;
208 if (depthmode
== 0) /* GL_LUMINANCE */
209 tgt
[1].SrcReg
[2].Swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_Z
);
210 else if (depthmode
== 2) /* GL_ALPHA */
211 tgt
[1].SrcReg
[2].Swizzle
= SWIZZLE_WWWW
;
213 /* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
214 * r < tex <=> -tex+r < 0
215 * r >= tex <=> not (-tex+r < 0 */
216 if (comparefunc
== GL_LESS
|| comparefunc
== GL_GEQUAL
)
217 tgt
[1].SrcReg
[2].NegateBase
= tgt
[0].SrcReg
[2].NegateBase
^ NEGATE_XYZW
;
219 tgt
[1].SrcReg
[0].NegateBase
= tgt
[0].SrcReg
[0].NegateBase
^ NEGATE_XYZW
;
221 tgt
[2].Opcode
= OPCODE_CMP
;
222 tgt
[2].DstReg
= orig_inst
->DstReg
;
223 tgt
[2].SrcReg
[0].File
= PROGRAM_TEMPORARY
;
224 tgt
[2].SrcReg
[0].Index
= tgt
[1].DstReg
.Index
;
226 if (comparefunc
== GL_LESS
|| comparefunc
== GL_GREATER
) {
234 tgt
[2].SrcReg
[pass
].File
= PROGRAM_BUILTIN
;
235 tgt
[2].SrcReg
[pass
].Swizzle
= SWIZZLE_1111
;
236 tgt
[2].SrcReg
[fail
] = shadow_ambient(t
->Program
, inst
.TexSrcUnit
);
237 } else if (destredirect
) {
238 tgt
= radeonAppendInstructions(t
->Program
, 1);
240 tgt
->Opcode
= OPCODE_MOV
;
241 tgt
->DstReg
= orig_inst
->DstReg
;
242 tgt
->SrcReg
[0].File
= PROGRAM_TEMPORARY
;
243 tgt
->SrcReg
[0].Index
= inst
.DstReg
.Index
;
250 static void update_params(GLcontext
*ctx
, struct gl_fragment_program
*fp
)
252 /* Ask Mesa nicely to fill in ParameterValues for us */
253 if (fp
->Base
.Parameters
)
254 _mesa_load_state_parameters(ctx
, fp
->Base
.Parameters
);
259 * Transform the program to support fragment.position.
261 * Introduce a small fragment at the start of the program that will be
262 * the only code that directly reads the FRAG_ATTRIB_WPOS input.
263 * All other code pieces that reference that input will be rewritten
264 * to read from a newly allocated temporary.
267 void insert_WPOS_trailer(struct r300_fragment_program_compiler
*compiler
)
269 GLuint InputsRead
= compiler
->fp
->Base
.Base
.InputsRead
;
271 if (!(InputsRead
& FRAG_BIT_WPOS
))
274 static gl_state_index tokens
[STATE_LENGTH
] = {
275 STATE_INTERNAL
, STATE_R300_WINDOW_DIMENSION
, 0, 0, 0
277 struct prog_instruction
*fpi
;
280 GLuint tempregi
= _mesa_find_free_register(compiler
->program
, PROGRAM_TEMPORARY
);
282 _mesa_insert_instructions(compiler
->program
, 0, 3);
283 fpi
= compiler
->program
->Instructions
;
285 /* perspective divide */
286 fpi
[i
].Opcode
= OPCODE_RCP
;
288 fpi
[i
].DstReg
.File
= PROGRAM_TEMPORARY
;
289 fpi
[i
].DstReg
.Index
= tempregi
;
290 fpi
[i
].DstReg
.WriteMask
= WRITEMASK_W
;
291 fpi
[i
].DstReg
.CondMask
= COND_TR
;
293 fpi
[i
].SrcReg
[0].File
= PROGRAM_INPUT
;
294 fpi
[i
].SrcReg
[0].Index
= FRAG_ATTRIB_WPOS
;
295 fpi
[i
].SrcReg
[0].Swizzle
= SWIZZLE_WWWW
;
298 fpi
[i
].Opcode
= OPCODE_MUL
;
300 fpi
[i
].DstReg
.File
= PROGRAM_TEMPORARY
;
301 fpi
[i
].DstReg
.Index
= tempregi
;
302 fpi
[i
].DstReg
.WriteMask
= WRITEMASK_XYZ
;
303 fpi
[i
].DstReg
.CondMask
= COND_TR
;
305 fpi
[i
].SrcReg
[0].File
= PROGRAM_INPUT
;
306 fpi
[i
].SrcReg
[0].Index
= FRAG_ATTRIB_WPOS
;
307 fpi
[i
].SrcReg
[0].Swizzle
= SWIZZLE_XYZW
;
309 fpi
[i
].SrcReg
[1].File
= PROGRAM_TEMPORARY
;
310 fpi
[i
].SrcReg
[1].Index
= tempregi
;
311 fpi
[i
].SrcReg
[1].Swizzle
= SWIZZLE_WWWW
;
314 /* viewport transformation */
315 window_index
= _mesa_add_state_reference(compiler
->program
->Parameters
, tokens
);
317 fpi
[i
].Opcode
= OPCODE_MAD
;
319 fpi
[i
].DstReg
.File
= PROGRAM_TEMPORARY
;
320 fpi
[i
].DstReg
.Index
= tempregi
;
321 fpi
[i
].DstReg
.WriteMask
= WRITEMASK_XYZ
;
322 fpi
[i
].DstReg
.CondMask
= COND_TR
;
324 fpi
[i
].SrcReg
[0].File
= PROGRAM_TEMPORARY
;
325 fpi
[i
].SrcReg
[0].Index
= tempregi
;
326 fpi
[i
].SrcReg
[0].Swizzle
=
327 MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ZERO
);
329 fpi
[i
].SrcReg
[1].File
= PROGRAM_STATE_VAR
;
330 fpi
[i
].SrcReg
[1].Index
= window_index
;
331 fpi
[i
].SrcReg
[1].Swizzle
=
332 MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ZERO
);
334 fpi
[i
].SrcReg
[2].File
= PROGRAM_STATE_VAR
;
335 fpi
[i
].SrcReg
[2].Index
= window_index
;
336 fpi
[i
].SrcReg
[2].Swizzle
=
337 MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ZERO
);
340 for (; i
< compiler
->program
->NumInstructions
; ++i
) {
342 for (reg
= 0; reg
< 3; reg
++) {
343 if (fpi
[i
].SrcReg
[reg
].File
== PROGRAM_INPUT
&&
344 fpi
[i
].SrcReg
[reg
].Index
== FRAG_ATTRIB_WPOS
) {
345 fpi
[i
].SrcReg
[reg
].File
= PROGRAM_TEMPORARY
;
346 fpi
[i
].SrcReg
[reg
].Index
= tempregi
;
353 static void nqssadce_init(struct nqssadce_state
* s
)
355 s
->Outputs
[FRAG_RESULT_COLOR
].Sourced
= WRITEMASK_XYZW
;
356 s
->Outputs
[FRAG_RESULT_DEPTH
].Sourced
= WRITEMASK_W
;
360 static GLuint
build_dtm(GLuint depthmode
)
364 case GL_LUMINANCE
: return 0;
365 case GL_INTENSITY
: return 1;
366 case GL_ALPHA
: return 2;
370 static GLuint
build_func(GLuint comparefunc
)
372 return comparefunc
- GL_NEVER
;
377 * Collect all external state that is relevant for compiling the given
380 static void build_state(
382 struct r300_fragment_program
*fp
,
383 struct r300_fragment_program_external_state
*state
)
387 _mesa_bzero(state
, sizeof(*state
));
389 for(unit
= 0; unit
< 16; ++unit
) {
390 if (fp
->Base
.Base
.ShadowSamplers
& (1 << unit
)) {
391 struct gl_texture_object
* tex
= r300
->radeon
.glCtx
->Texture
.Unit
[unit
]._Current
;
393 state
->unit
[unit
].depth_texture_mode
= build_dtm(tex
->DepthMode
);
394 state
->unit
[unit
].texture_compare_func
= build_func(tex
->CompareFunc
);
400 void r300TranslateFragmentShader(GLcontext
*ctx
, struct gl_fragment_program
*fp
)
402 r300ContextPtr r300
= R300_CONTEXT(ctx
);
403 struct r300_fragment_program
*r300_fp
= (struct r300_fragment_program
*)fp
;
404 struct r300_fragment_program_external_state state
;
406 build_state(r300
, r300_fp
, &state
);
407 if (_mesa_memcmp(&r300_fp
->state
, &state
, sizeof(state
))) {
408 /* TODO: cache compiled programs */
409 r300_fp
->translated
= GL_FALSE
;
410 _mesa_memcpy(&r300_fp
->state
, &state
, sizeof(state
));
413 if (!r300_fp
->translated
) {
414 struct r300_fragment_program_compiler compiler
;
416 compiler
.r300
= r300
;
417 compiler
.fp
= r300_fp
;
418 compiler
.code
= &r300_fp
->code
;
419 compiler
.program
= _mesa_clone_program(ctx
, &fp
->Base
);
421 if (RADEON_DEBUG
& DEBUG_PIXEL
) {
422 _mesa_printf("Fragment Program: Initial program:\n");
423 _mesa_print_program(compiler
.program
);
426 insert_WPOS_trailer(&compiler
);
428 struct radeon_program_transformation transformations
[] = {
429 { &transform_TEX
, &compiler
},
430 { &radeonTransformALU
, 0 },
431 { &radeonTransformTrigSimple
, 0 }
433 radeonLocalTransform(ctx
, compiler
.program
, 3, transformations
);
435 if (RADEON_DEBUG
& DEBUG_PIXEL
) {
436 _mesa_printf("Fragment Program: After native rewrite:\n");
437 _mesa_print_program(compiler
.program
);
440 struct radeon_nqssadce_descr nqssadce
= {
441 .Init
= &nqssadce_init
,
442 .IsNativeSwizzle
= &r300FPIsNativeSwizzle
,
443 .BuildSwizzle
= &r300FPBuildSwizzle
,
444 .RewriteDepthOut
= GL_TRUE
446 radeonNqssaDce(ctx
, compiler
.program
, &nqssadce
);
448 if (RADEON_DEBUG
& DEBUG_PIXEL
) {
449 _mesa_printf("Compiler: after NqSSA-DCE:\n");
450 _mesa_print_program(compiler
.program
);
453 if (!r300
->vtbl
.FragmentProgramEmit(&compiler
))
454 r300_fp
->error
= GL_TRUE
;
456 /* Subtle: Rescue any parameters that have been added during transformations */
457 _mesa_free_parameter_list(fp
->Base
.Parameters
);
458 fp
->Base
.Parameters
= compiler
.program
->Parameters
;
459 compiler
.program
->Parameters
= 0;
461 _mesa_reference_program(ctx
, &compiler
.program
, NULL
);
463 r300_fp
->translated
= GL_TRUE
;
465 r300UpdateStateParameters(ctx
, _NEW_PROGRAM
);
467 if (r300_fp
->error
|| (RADEON_DEBUG
& DEBUG_PIXEL
))
468 r300
->vtbl
.FragmentProgramDump(&r300_fp
->code
);
471 update_params(ctx
, fp
);
474 /* just some random things... */
475 void r300FragmentProgramDump(union rX00_fragment_program_code
*c
)
477 struct r300_fragment_program_code
*code
= &c
->r300
;
481 fprintf(stderr
, "pc=%d*************************************\n", pc
++);
483 fprintf(stderr
, "Hardware program\n");
484 fprintf(stderr
, "----------------\n");
486 for (n
= 0; n
< (code
->cur_node
+ 1); n
++) {
487 fprintf(stderr
, "NODE %d: alu_offset: %d, tex_offset: %d, "
488 "alu_end: %d, tex_end: %d, flags: %08x\n", n
,
489 code
->node
[n
].alu_offset
,
490 code
->node
[n
].tex_offset
,
491 code
->node
[n
].alu_end
, code
->node
[n
].tex_end
,
492 code
->node
[n
].flags
);
494 if (n
> 0 || code
->first_node_has_tex
) {
495 fprintf(stderr
, " TEX:\n");
496 for (i
= code
->node
[n
].tex_offset
;
497 i
<= code
->node
[n
].tex_offset
+ code
->node
[n
].tex_end
;
502 inst
[i
] >> R300_TEX_INST_SHIFT
) &
507 case R300_TEX_OP_KIL
:
510 case R300_TEX_OP_TXP
:
513 case R300_TEX_OP_TXB
:
521 " %s t%i, %c%i, texture[%i] (%08x)\n",
524 inst
[i
] >> R300_DST_ADDR_SHIFT
) & 31,
527 inst
[i
] >> R300_SRC_ADDR_SHIFT
) & 31,
529 inst
[i
] & R300_TEX_ID_MASK
) >>
535 for (i
= code
->node
[n
].alu_offset
;
536 i
<= code
->node
[n
].alu_offset
+ code
->node
[n
].alu_end
; ++i
) {
537 char srcc
[3][10], dstc
[20];
538 char srca
[3][10], dsta
[20];
541 char flags
[5], tmp
[10];
543 for (j
= 0; j
< 3; ++j
) {
544 int regc
= code
->alu
.inst
[i
].inst1
>> (j
* 6);
545 int rega
= code
->alu
.inst
[i
].inst3
>> (j
* 6);
547 sprintf(srcc
[j
], "%c%i",
548 (regc
& 32) ? 'c' : 't', regc
& 31);
549 sprintf(srca
[j
], "%c%i",
550 (rega
& 32) ? 'c' : 't', rega
& 31);
554 sprintf(flags
, "%s%s%s",
556 inst1
& R300_ALU_DSTC_REG_X
) ? "x" : "",
558 inst1
& R300_ALU_DSTC_REG_Y
) ? "y" : "",
560 inst1
& R300_ALU_DSTC_REG_Z
) ? "z" : "");
562 sprintf(dstc
, "t%i.%s ",
564 inst1
>> R300_ALU_DSTC_SHIFT
) & 31,
567 sprintf(flags
, "%s%s%s",
569 inst1
& R300_ALU_DSTC_OUTPUT_X
) ? "x" : "",
571 inst1
& R300_ALU_DSTC_OUTPUT_Y
) ? "y" : "",
573 inst1
& R300_ALU_DSTC_OUTPUT_Z
) ? "z" : "");
575 sprintf(tmp
, "o%i.%s",
577 inst1
>> R300_ALU_DSTC_SHIFT
) & 31,
583 if (code
->alu
.inst
[i
].inst3
& R300_ALU_DSTA_REG
) {
584 sprintf(dsta
, "t%i.w ",
586 inst3
>> R300_ALU_DSTA_SHIFT
) & 31);
588 if (code
->alu
.inst
[i
].inst3
& R300_ALU_DSTA_OUTPUT
) {
589 sprintf(tmp
, "o%i.w ",
591 inst3
>> R300_ALU_DSTA_SHIFT
) & 31);
594 if (code
->alu
.inst
[i
].inst3
& R300_ALU_DSTA_DEPTH
) {
599 "%3i: xyz: %3s %3s %3s -> %-20s (%08x)\n"
600 " w: %3s %3s %3s -> %-20s (%08x)\n", i
,
601 srcc
[0], srcc
[1], srcc
[2], dstc
,
602 code
->alu
.inst
[i
].inst1
, srca
[0], srca
[1],
603 srca
[2], dsta
, code
->alu
.inst
[i
].inst3
);
605 for (j
= 0; j
< 3; ++j
) {
606 int regc
= code
->alu
.inst
[i
].inst0
>> (j
* 7);
607 int rega
= code
->alu
.inst
[i
].inst2
>> (j
* 7);
614 case R300_ALU_ARGC_SRC0C_XYZ
:
615 sprintf(buf
, "%s.xyz",
618 case R300_ALU_ARGC_SRC0C_XXX
:
619 sprintf(buf
, "%s.xxx",
622 case R300_ALU_ARGC_SRC0C_YYY
:
623 sprintf(buf
, "%s.yyy",
626 case R300_ALU_ARGC_SRC0C_ZZZ
:
627 sprintf(buf
, "%s.zzz",
632 sprintf(buf
, "%s.www", srca
[d
- 12]);
633 } else if (d
== 20) {
635 } else if (d
== 21) {
637 } else if (d
== 22) {
639 } else if (d
>= 23 && d
< 32) {
643 sprintf(buf
, "%s.yzx",
647 sprintf(buf
, "%s.zxy",
651 sprintf(buf
, "%s.Wzy",
656 sprintf(buf
, "%i", d
);
659 sprintf(argc
[j
], "%s%s%s%s",
660 (regc
& 32) ? "-" : "",
661 (regc
& 64) ? "|" : "",
662 buf
, (regc
& 64) ? "|" : "");
666 sprintf(buf
, "%s.%c", srcc
[d
/ 3],
667 'x' + (char)(d
% 3));
669 sprintf(buf
, "%s.w", srca
[d
- 9]);
670 } else if (d
== 16) {
672 } else if (d
== 17) {
674 } else if (d
== 18) {
677 sprintf(buf
, "%i", d
);
680 sprintf(arga
[j
], "%s%s%s%s",
681 (rega
& 32) ? "-" : "",
682 (rega
& 64) ? "|" : "",
683 buf
, (rega
& 64) ? "|" : "");
686 fprintf(stderr
, " xyz: %8s %8s %8s op: %08x\n"
687 " w: %8s %8s %8s op: %08x\n",
688 argc
[0], argc
[1], argc
[2],
689 code
->alu
.inst
[i
].inst0
, arga
[0], arga
[1],
690 arga
[2], code
->alu
.inst
[i
].inst2
);