2 * Copyright © 2017 Gert Wollny
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
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
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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 #include "st_glsl_to_tgsi_temprename.h"
25 #include <tgsi/tgsi_info.h>
26 #include <tgsi/tgsi_strings.h>
27 #include <program/prog_instruction.h>
31 /* std::sort is significantly faster than qsort */
40 #include <program/prog_print.h>
41 #include <util/debug.h>
46 using std::numeric_limits
;
48 /* Without c++11 define the nullptr for forward-compatibility
49 * and better readibility */
50 #if __cplusplus < 201103L
55 /* Helper function to check whether we want to seen debugging output */
56 static inline bool is_debug_enabled ()
58 static int debug_enabled
= -1;
59 if (debug_enabled
< 0)
60 debug_enabled
= env_var_as_boolean("GLSL_TO_TGSI_RENAME_DEBUG", false);
61 return debug_enabled
> 0;
63 #define RENAME_DEBUG(X) if (is_debug_enabled()) do { X; } while (false);
65 #define RENAME_DEBUG(X)
70 enum prog_scope_type
{
71 outer_scope
, /* Outer program scope */
72 loop_body
, /* Inside a loop */
73 if_branch
, /* Inside if branch */
74 else_branch
, /* Inside else branch */
75 switch_body
, /* Inside switch statmenet */
76 switch_case_branch
, /* Inside switch case statmenet */
77 switch_default_branch
, /* Inside switch default statmenet */
83 prog_scope(prog_scope
*parent
, prog_scope_type type
, int id
,
84 int depth
, int begin
);
86 prog_scope_type
type() const;
87 prog_scope
*parent() const;
88 int nesting_depth() const;
92 int loop_break_line() const;
94 const prog_scope
*in_ifelse_scope() const;
95 const prog_scope
*in_switchcase_scope() const;
96 const prog_scope
*innermost_loop() const;
97 const prog_scope
*outermost_loop() const;
98 const prog_scope
*enclosing_conditional() const;
100 bool is_loop() const;
101 bool is_in_loop() const;
102 bool is_conditional() const;
103 bool is_conditional_in_loop() const;
105 bool break_is_for_switchcase() const;
106 bool contains_range_of(const prog_scope
& other
) const;
107 const st_src_reg
*switch_register() const;
109 void set_end(int end
);
110 void set_loop_break_line(int line
);
113 prog_scope_type scope_type
;
115 int scope_nesting_depth
;
119 prog_scope
*parent_scope
;
120 const st_src_reg
*switch_reg
;
123 /* Some storage class to encapsulate the prog_scope (de-)allocations */
124 class prog_scope_storage
{
126 prog_scope_storage(void *mem_ctx
, int n
);
127 ~prog_scope_storage();
128 prog_scope
* create(prog_scope
*p
, prog_scope_type type
, int id
,
129 int lvl
, int s_begin
);
136 class temp_comp_access
{
139 void record_read(int line
, prog_scope
*scope
);
140 void record_write(int line
, prog_scope
*scope
);
141 lifetime
get_required_lifetime();
143 void propagate_lifetime_to_dominant_write_scope();
145 prog_scope
*last_read_scope
;
146 prog_scope
*first_read_scope
;
147 prog_scope
*first_write_scope
;
152 bool keep_for_full_loop
;
158 void record_read(int line
, prog_scope
*scope
, int swizzle
);
159 void record_write(int line
, prog_scope
*scope
, int writemask
);
160 lifetime
get_required_lifetime();
162 void update_access_mask(int mask
);
164 temp_comp_access comp
[4];
166 bool needs_component_tracking
;
169 prog_scope_storage::prog_scope_storage(void *mc
, int n
):
173 storage
= ralloc_array(mem_ctx
, prog_scope
, n
);
176 prog_scope_storage::~prog_scope_storage()
178 ralloc_free(storage
);
182 prog_scope_storage::create(prog_scope
*p
, prog_scope_type type
, int id
,
183 int lvl
, int s_begin
)
185 storage
[current_slot
] = prog_scope(p
, type
, id
, lvl
, s_begin
);
186 return &storage
[current_slot
++];
189 prog_scope::prog_scope(prog_scope
*parent
, prog_scope_type type
, int id
,
190 int depth
, int scope_begin
):
193 scope_nesting_depth(depth
),
194 scope_begin(scope_begin
),
196 break_loop_line(numeric_limits
<int>::max()),
197 parent_scope(parent
),
202 prog_scope_type
prog_scope::type() const
207 prog_scope
*prog_scope::parent() const
212 int prog_scope::nesting_depth() const
214 return scope_nesting_depth
;
217 bool prog_scope::is_loop() const
219 return (scope_type
== loop_body
);
222 bool prog_scope::is_in_loop() const
224 if (scope_type
== loop_body
)
228 return parent_scope
->is_in_loop();
233 bool prog_scope::is_conditional_in_loop() const
235 return is_conditional() && is_in_loop();
238 const prog_scope
*prog_scope::innermost_loop() const
240 if (scope_type
== loop_body
)
244 return parent_scope
->innermost_loop();
249 const prog_scope
*prog_scope::outermost_loop() const
251 const prog_scope
*loop
= nullptr;
252 const prog_scope
*p
= this;
255 if (p
->type() == loop_body
)
263 const prog_scope
*prog_scope::enclosing_conditional() const
265 if (is_conditional())
269 return parent_scope
->enclosing_conditional();
274 bool prog_scope::contains_range_of(const prog_scope
& other
) const
276 return (begin() <= other
.begin()) && (end() >= other
.end());
279 bool prog_scope::is_conditional() const
281 return scope_type
== if_branch
||
282 scope_type
== else_branch
||
283 scope_type
== switch_case_branch
||
284 scope_type
== switch_default_branch
;
287 const prog_scope
*prog_scope::in_ifelse_scope() const
289 if (scope_type
== if_branch
||
290 scope_type
== else_branch
)
294 return parent_scope
->in_ifelse_scope();
299 const st_src_reg
*prog_scope::switch_register() const
304 const prog_scope
*prog_scope::in_switchcase_scope() const
306 if (scope_type
== switch_case_branch
||
307 scope_type
== switch_default_branch
)
311 return parent_scope
->in_switchcase_scope();
316 bool prog_scope::break_is_for_switchcase() const
318 if (scope_type
== loop_body
)
321 if (scope_type
== switch_case_branch
||
322 scope_type
== switch_default_branch
||
323 scope_type
== switch_body
)
327 return parent_scope
->break_is_for_switchcase();
332 int prog_scope::id() const
337 int prog_scope::begin() const
342 int prog_scope::end() const
347 void prog_scope::set_end(int end
)
353 void prog_scope::set_loop_break_line(int line
)
355 if (scope_type
== loop_body
) {
356 break_loop_line
= MIN2(break_loop_line
, line
);
359 parent()->set_loop_break_line(line
);
363 int prog_scope::loop_break_line() const
365 return break_loop_line
;
368 temp_access::temp_access():
370 needs_component_tracking(false)
374 void temp_access::update_access_mask(int mask
)
376 if (access_mask
&& access_mask
!= mask
)
377 needs_component_tracking
= true;
381 void temp_access::record_write(int line
, prog_scope
*scope
, int writemask
)
383 update_access_mask(writemask
);
385 if (writemask
& WRITEMASK_X
)
386 comp
[0].record_write(line
, scope
);
387 if (writemask
& WRITEMASK_Y
)
388 comp
[1].record_write(line
, scope
);
389 if (writemask
& WRITEMASK_Z
)
390 comp
[2].record_write(line
, scope
);
391 if (writemask
& WRITEMASK_W
)
392 comp
[3].record_write(line
, scope
);
395 void temp_access::record_read(int line
, prog_scope
*scope
, int swizzle
)
398 for (int idx
= 0; idx
< 4; ++idx
) {
399 int swz
= GET_SWZ(swizzle
, idx
);
400 readmask
|= (1 << swz
) & 0xF;
402 update_access_mask(readmask
);
404 if (readmask
& WRITEMASK_X
)
405 comp
[0].record_read(line
, scope
);
406 if (readmask
& WRITEMASK_Y
)
407 comp
[1].record_read(line
, scope
);
408 if (readmask
& WRITEMASK_Z
)
409 comp
[2].record_read(line
, scope
);
410 if (readmask
& WRITEMASK_W
)
411 comp
[3].record_read(line
, scope
);
414 inline static lifetime
make_lifetime(int b
, int e
)
422 lifetime
temp_access::get_required_lifetime()
424 lifetime result
= make_lifetime(-1, -1);
426 unsigned mask
= access_mask
;
428 unsigned chan
= u_bit_scan(&mask
);
429 lifetime lt
= comp
[chan
].get_required_lifetime();
432 if ((result
.begin
< 0) || (result
.begin
> lt
.begin
))
433 result
.begin
= lt
.begin
;
436 if (lt
.end
> result
.end
)
439 if (!needs_component_tracking
)
445 temp_comp_access::temp_comp_access():
446 last_read_scope(nullptr),
447 first_read_scope(nullptr),
448 first_write_scope(nullptr),
452 first_read(numeric_limits
<int>::max())
456 void temp_comp_access::record_read(int line
, prog_scope
*scope
)
458 last_read_scope
= scope
;
461 if (first_read
> line
) {
463 first_read_scope
= scope
;
467 void temp_comp_access::record_write(int line
, prog_scope
*scope
)
471 if (first_write
< 0) {
473 first_write_scope
= scope
;
477 void temp_comp_access::propagate_lifetime_to_dominant_write_scope()
479 first_write
= first_write_scope
->begin();
480 int lr
= first_write_scope
->end();
486 lifetime
temp_comp_access::get_required_lifetime()
488 bool keep_for_full_loop
= false;
490 /* This register component is not used at all, or only read,
491 * mark it as unused and ignore it when renaming.
492 * glsl_to_tgsi_visitor::renumber_registers will take care of
493 * eliminating registers that are not written to.
496 return make_lifetime(-1, -1);
498 assert(first_write_scope
);
500 /* Only written to, just make sure the register component is not
501 * reused in the range it is used to write to
503 if (!last_read_scope
)
504 return make_lifetime(first_write
, last_write
+ 1);
506 const prog_scope
*enclosing_scope_first_read
= first_read_scope
;
507 const prog_scope
*enclosing_scope_first_write
= first_write_scope
;
509 /* We read before writing in a loop
510 * hence the value must survive the loops
512 if ((first_read
<= first_write
) &&
513 first_read_scope
->is_in_loop()) {
514 keep_for_full_loop
= true;
515 enclosing_scope_first_read
= first_read_scope
->outermost_loop();
518 /* A conditional write within a nested loop must survive
519 * the outermost loop, but only if it is read outside
520 * the condition scope where we write.
522 const prog_scope
*conditional
= enclosing_scope_first_write
->enclosing_conditional();
523 if (conditional
&& conditional
->is_in_loop() &&
524 !conditional
->contains_range_of(*last_read_scope
)) {
525 keep_for_full_loop
= true;
526 enclosing_scope_first_write
= conditional
->outermost_loop();
529 /* Evaluate the scope that is shared by all: required first write scope,
530 * required first read before write scope, and last read scope.
532 const prog_scope
*enclosing_scope
= enclosing_scope_first_read
;
533 if (enclosing_scope_first_write
->contains_range_of(*enclosing_scope
))
534 enclosing_scope
= enclosing_scope_first_write
;
536 if (enclosing_scope_first_read
->contains_range_of(*enclosing_scope
))
537 enclosing_scope
= enclosing_scope_first_read
;
539 while (!enclosing_scope
->contains_range_of(*enclosing_scope_first_write
) ||
540 !enclosing_scope
->contains_range_of(*last_read_scope
)) {
541 enclosing_scope
= enclosing_scope
->parent();
542 assert(enclosing_scope
);
545 /* Propagate the last read scope to the target scope */
546 while (enclosing_scope
->nesting_depth() < last_read_scope
->nesting_depth()) {
547 /* If the read is in a loop and we have to move up the scope we need to
548 * extend the life time to the end of this current loop because at this
549 * point we don't know whether the component was written before
550 * un-conditionally in the same loop.
552 if (last_read_scope
->is_loop())
553 last_read
= last_read_scope
->end();
555 last_read_scope
= last_read_scope
->parent();
558 /* If the variable has to be kept for the whole loop, and we
559 * are currently in a loop, then propagate the life time.
561 if (keep_for_full_loop
&& first_write_scope
->is_loop())
562 propagate_lifetime_to_dominant_write_scope();
564 /* Propagate the first_dominant_write scope to the target scope */
565 while (enclosing_scope
->nesting_depth() < first_write_scope
->nesting_depth()) {
566 /* Propagate lifetime if there was a break in a loop and the write was
567 * after the break inside that loop. Note, that this is only needed if
568 * we move up in the scopes.
570 if (first_write_scope
->loop_break_line() < first_write
) {
571 keep_for_full_loop
= true;
572 propagate_lifetime_to_dominant_write_scope();
575 first_write_scope
= first_write_scope
->parent();
577 /* Propagte lifetime if we are now in a loop */
578 if (keep_for_full_loop
&& first_write_scope
->is_loop())
579 propagate_lifetime_to_dominant_write_scope();
582 /* The last write past the last read is dead code, but we have to
583 * ensure that the component is not reused too early, hence extend the
584 * lifetime past the last write.
586 if (last_write
>= last_read
)
587 last_read
= last_write
+ 1;
589 /* Here we are at the same scope, all is resolved */
590 return make_lifetime(first_write
, last_read
);
596 /* Function used for debugging. */
597 static void dump_instruction(int line
, prog_scope
*scope
,
598 const glsl_to_tgsi_instruction
& inst
);
601 /* Scan the program and estimate the required register life times.
602 * The array lifetimes must be pre-allocated
605 get_temp_registers_required_lifetimes(void *mem_ctx
, exec_list
*instructions
,
606 int ntemps
, struct lifetime
*lifetimes
)
612 bool is_at_end
= false;
615 /* Count scopes to allocate the needed space without the need for
618 foreach_in_list(glsl_to_tgsi_instruction
, inst
, instructions
) {
619 if (inst
->op
== TGSI_OPCODE_BGNLOOP
||
620 inst
->op
== TGSI_OPCODE_SWITCH
||
621 inst
->op
== TGSI_OPCODE_CASE
||
622 inst
->op
== TGSI_OPCODE_IF
||
623 inst
->op
== TGSI_OPCODE_UIF
||
624 inst
->op
== TGSI_OPCODE_ELSE
||
625 inst
->op
== TGSI_OPCODE_DEFAULT
)
629 prog_scope_storage
scopes(mem_ctx
, n_scopes
);
630 temp_access
*acc
= new temp_access
[ntemps
];
632 prog_scope
*cur_scope
= scopes
.create(nullptr, outer_scope
, 0, 0, line
);
634 RENAME_DEBUG(cerr
<< "========= Begin shader ============\n");
636 foreach_in_list(glsl_to_tgsi_instruction
, inst
, instructions
) {
638 assert(!"GLSL_TO_TGSI: shader has instructions past end marker");
642 RENAME_DEBUG(dump_instruction(line
, cur_scope
, *inst
));
645 case TGSI_OPCODE_BGNLOOP
: {
646 cur_scope
= scopes
.create(cur_scope
, loop_body
, loop_id
++,
647 cur_scope
->nesting_depth() + 1, line
);
650 case TGSI_OPCODE_ENDLOOP
: {
651 cur_scope
->set_end(line
);
652 cur_scope
= cur_scope
->parent();
657 case TGSI_OPCODE_UIF
: {
658 assert(num_inst_src_regs(inst
) == 1);
659 const st_src_reg
& src
= inst
->src
[0];
660 if (src
.file
== PROGRAM_TEMPORARY
)
661 acc
[src
.index
].record_read(line
, cur_scope
, src
.swizzle
);
662 cur_scope
= scopes
.create(cur_scope
, if_branch
, if_id
++,
663 cur_scope
->nesting_depth() + 1, line
+ 1);
666 case TGSI_OPCODE_ELSE
: {
667 assert(cur_scope
->type() == if_branch
);
668 cur_scope
->set_end(line
- 1);
669 cur_scope
= scopes
.create(cur_scope
->parent(), else_branch
,
670 cur_scope
->id(), cur_scope
->nesting_depth(),
674 case TGSI_OPCODE_END
: {
675 cur_scope
->set_end(line
);
679 case TGSI_OPCODE_ENDIF
: {
680 cur_scope
->set_end(line
- 1);
681 cur_scope
= cur_scope
->parent();
685 case TGSI_OPCODE_SWITCH
: {
686 assert(num_inst_src_regs(inst
) == 1);
687 const st_src_reg
& src
= inst
->src
[0];
688 prog_scope
*scope
= scopes
.create(cur_scope
, switch_body
, switch_id
++,
689 cur_scope
->nesting_depth() + 1, line
);
690 /* We record the read only for the SWITCH statement itself, like it
691 * is used by the only consumer of TGSI_OPCODE_SWITCH in tgsi_exec.c.
693 if (src
.file
== PROGRAM_TEMPORARY
)
694 acc
[src
.index
].record_read(line
, cur_scope
, src
.swizzle
);
698 case TGSI_OPCODE_ENDSWITCH
: {
699 cur_scope
->set_end(line
- 1);
700 /* Remove the case level, it might not have been
701 * closed with a break.
703 if (cur_scope
->type() != switch_body
)
704 cur_scope
= cur_scope
->parent();
706 cur_scope
= cur_scope
->parent();
710 case TGSI_OPCODE_CASE
: {
711 /* Take care of tracking the registers. */
712 prog_scope
*switch_scope
= cur_scope
->type() == switch_body
?
713 cur_scope
: cur_scope
->parent();
715 assert(num_inst_src_regs(inst
) == 1);
716 const st_src_reg
& src
= inst
->src
[0];
717 if (src
.file
== PROGRAM_TEMPORARY
)
718 acc
[src
.index
].record_read(line
, switch_scope
, src
.swizzle
);
720 /* Fall through to allocate the scope. */
722 case TGSI_OPCODE_DEFAULT
: {
723 prog_scope_type t
= inst
->op
== TGSI_OPCODE_CASE
? switch_case_branch
724 : switch_default_branch
;
725 prog_scope
*switch_scope
= (cur_scope
->type() == switch_body
) ?
726 cur_scope
: cur_scope
->parent();
727 assert(switch_scope
->type() == switch_body
);
728 prog_scope
*scope
= scopes
.create(switch_scope
, t
,
730 switch_scope
->nesting_depth() + 1,
732 /* Previous case falls through, so scope was not yet closed. */
733 if ((cur_scope
!= switch_scope
) && (cur_scope
->end() == -1))
734 cur_scope
->set_end(line
- 1);
738 case TGSI_OPCODE_BRK
: {
739 if (cur_scope
->break_is_for_switchcase()) {
740 cur_scope
->set_end(line
- 1);
742 cur_scope
->set_loop_break_line(line
);
747 for (unsigned j
= 0; j
< num_inst_src_regs(inst
); j
++) {
748 const st_src_reg
& src
= inst
->src
[j
];
749 if (src
.file
== PROGRAM_TEMPORARY
)
750 acc
[src
.index
].record_read(line
, cur_scope
, src
.swizzle
);
752 for (unsigned j
= 0; j
< inst
->tex_offset_num_offset
; j
++) {
753 const st_src_reg
& src
= inst
->tex_offsets
[j
];
754 if (src
.file
== PROGRAM_TEMPORARY
)
755 acc
[src
.index
].record_read(line
, cur_scope
, src
.swizzle
);
757 for (unsigned j
= 0; j
< num_inst_dst_regs(inst
); j
++) {
758 const st_dst_reg
& dst
= inst
->dst
[j
];
759 if (dst
.file
== PROGRAM_TEMPORARY
)
760 acc
[dst
.index
].record_write(line
, cur_scope
, dst
.writemask
);
767 RENAME_DEBUG(cerr
<< "==================================\n\n");
769 /* Make sure last scope is closed, even though no
770 * TGSI_OPCODE_END was given.
772 if (cur_scope
->end() < 0)
773 cur_scope
->set_end(line
- 1);
775 RENAME_DEBUG(cerr
<< "========= lifetimes ==============\n");
776 for(int i
= 0; i
< ntemps
; ++i
) {
777 RENAME_DEBUG(cerr
<< setw(4) << i
);
778 lifetimes
[i
] = acc
[i
].get_required_lifetime();
779 RENAME_DEBUG(cerr
<< ": [" << lifetimes
[i
].begin
<< ", "
780 << lifetimes
[i
].end
<< "]\n");
782 RENAME_DEBUG(cerr
<< "==================================\n\n");
787 /* Code below used for debugging */
789 static const char swizzle_txt
[] = "xyzw";
791 static const char *tgsi_file_names
[PROGRAM_FILE_MAX
] = {
792 "TEMP", "ARRAY", "IN", "OUT", "STATE", "CONST",
793 "UNIFORM", "WO", "ADDR", "SAMPLER", "SV", "UNDEF",
794 "IMM", "BUF", "MEM", "IMAGE"
798 void dump_instruction(int line
, prog_scope
*scope
,
799 const glsl_to_tgsi_instruction
& inst
)
801 const struct tgsi_opcode_info
*info
= tgsi_get_opcode_info(inst
.op
);
803 int indent
= scope
->nesting_depth();
804 if ((scope
->type() == switch_case_branch
||
805 scope
->type() == switch_default_branch
) &&
806 (info
->opcode
== TGSI_OPCODE_CASE
||
807 info
->opcode
== TGSI_OPCODE_DEFAULT
))
810 if (info
->opcode
== TGSI_OPCODE_ENDIF
||
811 info
->opcode
== TGSI_OPCODE_ELSE
||
812 info
->opcode
== TGSI_OPCODE_ENDLOOP
||
813 info
->opcode
== TGSI_OPCODE_ENDSWITCH
)
816 cerr
<< setw(4) << line
<< ": ";
817 for (int i
= 0; i
< indent
; ++i
)
819 cerr
<< tgsi_get_opcode_name(info
->opcode
) << " ";
821 bool has_operators
= false;
822 for (unsigned j
= 0; j
< num_inst_dst_regs(&inst
); j
++) {
823 has_operators
= true;
827 const st_dst_reg
& dst
= inst
.dst
[j
];
828 cerr
<< tgsi_file_names
[dst
.file
];
830 if (dst
.file
== PROGRAM_ARRAY
)
831 cerr
<< "(" << dst
.array_id
<< ")";
833 cerr
<< "[" << dst
.index
<< "]";
835 if (dst
.writemask
!= TGSI_WRITEMASK_XYZW
) {
837 if (dst
.writemask
& TGSI_WRITEMASK_X
) cerr
<< "x";
838 if (dst
.writemask
& TGSI_WRITEMASK_Y
) cerr
<< "y";
839 if (dst
.writemask
& TGSI_WRITEMASK_Z
) cerr
<< "z";
840 if (dst
.writemask
& TGSI_WRITEMASK_W
) cerr
<< "w";
846 for (unsigned j
= 0; j
< num_inst_src_regs(&inst
); j
++) {
850 const st_src_reg
& src
= inst
.src
[j
];
851 cerr
<< tgsi_file_names
[src
.file
]
852 << "[" << src
.index
<< "]";
853 if (src
.swizzle
!= SWIZZLE_XYZW
) {
855 for (int idx
= 0; idx
< 4; ++idx
) {
856 int swz
= GET_SWZ(src
.swizzle
, idx
);
858 cerr
<< swizzle_txt
[swz
];
864 if (inst
.tex_offset_num_offset
> 0) {
865 cerr
<< ", TEXOFS: ";
866 for (unsigned j
= 0; j
< inst
.tex_offset_num_offset
; j
++) {
870 const st_src_reg
& src
= inst
.tex_offsets
[j
];
871 cerr
<< tgsi_file_names
[src
.file
]
872 << "[" << src
.index
<< "]";
873 if (src
.swizzle
!= SWIZZLE_XYZW
) {
875 for (int idx
= 0; idx
< 4; ++idx
) {
876 int swz
= GET_SWZ(src
.swizzle
, idx
);
878 cerr
<< swizzle_txt
[swz
];