2 * Copyright © 2016-2017 Broadcom
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 DEALINGS
24 #include "v3d_compiler.h"
27 vir_get_non_sideband_nsrc(struct qinst
*inst
)
29 switch (inst
->qpu
.type
) {
30 case V3D_QPU_INSTR_TYPE_BRANCH
:
32 case V3D_QPU_INSTR_TYPE_ALU
:
33 if (inst
->qpu
.alu
.add
.op
!= V3D_QPU_A_NOP
)
34 return v3d_qpu_add_op_num_src(inst
->qpu
.alu
.add
.op
);
36 return v3d_qpu_mul_op_num_src(inst
->qpu
.alu
.mul
.op
);
43 vir_get_nsrc(struct qinst
*inst
)
45 int nsrc
= vir_get_non_sideband_nsrc(inst
);
47 if (vir_has_implicit_uniform(inst
))
54 vir_has_implicit_uniform(struct qinst
*inst
)
56 switch (inst
->qpu
.type
) {
57 case V3D_QPU_INSTR_TYPE_BRANCH
:
59 case V3D_QPU_INSTR_TYPE_ALU
:
60 switch (inst
->dst
.file
) {
64 return inst
->has_implicit_uniform
;
70 /* The sideband uniform for textures gets stored after the normal ALU
74 vir_get_implicit_uniform_src(struct qinst
*inst
)
76 return vir_get_nsrc(inst
) - 1;
80 * Returns whether the instruction has any side effects that must be
84 vir_has_side_effects(struct v3d_compile
*c
, struct qinst
*inst
)
86 switch (inst
->qpu
.type
) {
87 case V3D_QPU_INSTR_TYPE_BRANCH
:
89 case V3D_QPU_INSTR_TYPE_ALU
:
90 switch (inst
->qpu
.alu
.add
.op
) {
91 case V3D_QPU_A_SETREVF
:
92 case V3D_QPU_A_SETMSF
:
93 case V3D_QPU_A_VPMSETUP
:
99 switch (inst
->qpu
.alu
.mul
.op
) {
100 case V3D_QPU_M_MULTOP
:
107 if (inst
->qpu
.sig
.ldtmu
)
114 vir_is_float_input(struct qinst
*inst
)
116 /* XXX: More instrs */
117 switch (inst
->qpu
.type
) {
118 case V3D_QPU_INSTR_TYPE_BRANCH
:
120 case V3D_QPU_INSTR_TYPE_ALU
:
121 switch (inst
->qpu
.alu
.add
.op
) {
126 case V3D_QPU_A_FTOIN
:
132 switch (inst
->qpu
.alu
.mul
.op
) {
134 case V3D_QPU_M_VFMUL
:
146 vir_is_raw_mov(struct qinst
*inst
)
148 if (inst
->qpu
.type
!= V3D_QPU_INSTR_TYPE_ALU
||
149 (inst
->qpu
.alu
.mul
.op
!= V3D_QPU_M_FMOV
&&
150 inst
->qpu
.alu
.mul
.op
!= V3D_QPU_M_MOV
)) {
154 if (inst
->qpu
.alu
.add
.output_pack
!= V3D_QPU_PACK_NONE
||
155 inst
->qpu
.alu
.mul
.output_pack
!= V3D_QPU_PACK_NONE
) {
159 if (inst
->qpu
.flags
.ac
!= V3D_QPU_COND_NONE
||
160 inst
->qpu
.flags
.mc
!= V3D_QPU_COND_NONE
)
167 vir_is_add(struct qinst
*inst
)
169 return (inst
->qpu
.type
== V3D_QPU_INSTR_TYPE_ALU
&&
170 inst
->qpu
.alu
.add
.op
!= V3D_QPU_A_NOP
);
174 vir_is_mul(struct qinst
*inst
)
176 return (inst
->qpu
.type
== V3D_QPU_INSTR_TYPE_ALU
&&
177 inst
->qpu
.alu
.mul
.op
!= V3D_QPU_M_NOP
);
181 vir_is_tex(struct qinst
*inst
)
183 if (inst
->dst
.file
== QFILE_MAGIC
)
184 return v3d_qpu_magic_waddr_is_tmu(inst
->dst
.index
);
190 vir_depends_on_flags(struct qinst
*inst
)
192 if (inst
->qpu
.type
== V3D_QPU_INSTR_TYPE_BRANCH
) {
193 return (inst
->qpu
.branch
.cond
!= V3D_QPU_BRANCH_COND_ALWAYS
);
195 return (inst
->qpu
.flags
.ac
!= V3D_QPU_COND_NONE
&&
196 inst
->qpu
.flags
.mc
!= V3D_QPU_COND_NONE
);
201 vir_writes_r3(struct qinst
*inst
)
203 for (int i
= 0; i
< vir_get_nsrc(inst
); i
++) {
204 switch (inst
->src
[i
].file
) {
217 vir_writes_r4(struct qinst
*inst
)
219 switch (inst
->dst
.file
) {
221 switch (inst
->dst
.index
) {
222 case V3D_QPU_WADDR_RECIP
:
223 case V3D_QPU_WADDR_RSQRT
:
224 case V3D_QPU_WADDR_EXP
:
225 case V3D_QPU_WADDR_LOG
:
226 case V3D_QPU_WADDR_SIN
:
234 if (inst
->qpu
.sig
.ldtmu
)
241 vir_set_unpack(struct qinst
*inst
, int src
,
242 enum v3d_qpu_input_unpack unpack
)
244 assert(src
== 0 || src
== 1);
246 if (vir_is_add(inst
)) {
248 inst
->qpu
.alu
.add
.a_unpack
= unpack
;
250 inst
->qpu
.alu
.add
.b_unpack
= unpack
;
252 assert(vir_is_mul(inst
));
254 inst
->qpu
.alu
.mul
.a_unpack
= unpack
;
256 inst
->qpu
.alu
.mul
.b_unpack
= unpack
;
261 vir_set_cond(struct qinst
*inst
, enum v3d_qpu_cond cond
)
263 if (vir_is_add(inst
)) {
264 inst
->qpu
.flags
.ac
= cond
;
266 assert(vir_is_mul(inst
));
267 inst
->qpu
.flags
.mc
= cond
;
272 vir_set_pf(struct qinst
*inst
, enum v3d_qpu_pf pf
)
274 if (vir_is_add(inst
)) {
275 inst
->qpu
.flags
.apf
= pf
;
277 assert(vir_is_mul(inst
));
278 inst
->qpu
.flags
.mpf
= pf
;
284 vir_channels_written(struct qinst
*inst
)
286 if (vir_is_mul(inst
)) {
287 switch (inst
->dst
.pack
) {
288 case QPU_PACK_MUL_NOP
:
289 case QPU_PACK_MUL_8888
:
291 case QPU_PACK_MUL_8A
:
293 case QPU_PACK_MUL_8B
:
295 case QPU_PACK_MUL_8C
:
297 case QPU_PACK_MUL_8D
:
301 switch (inst
->dst
.pack
) {
303 case QPU_PACK_A_8888
:
304 case QPU_PACK_A_8888_SAT
:
305 case QPU_PACK_A_32_SAT
:
308 case QPU_PACK_A_8A_SAT
:
311 case QPU_PACK_A_8B_SAT
:
314 case QPU_PACK_A_8C_SAT
:
317 case QPU_PACK_A_8D_SAT
:
320 case QPU_PACK_A_16A_SAT
:
323 case QPU_PACK_A_16B_SAT
:
327 unreachable("Bad pack field");
332 vir_get_temp(struct v3d_compile
*c
)
336 reg
.file
= QFILE_TEMP
;
337 reg
.index
= c
->num_temps
++;
339 if (c
->num_temps
> c
->defs_array_size
) {
340 uint32_t old_size
= c
->defs_array_size
;
341 c
->defs_array_size
= MAX2(old_size
* 2, 16);
342 c
->defs
= reralloc(c
, c
->defs
, struct qinst
*,
344 memset(&c
->defs
[old_size
], 0,
345 sizeof(c
->defs
[0]) * (c
->defs_array_size
- old_size
));
352 vir_add_inst(enum v3d_qpu_add_op op
, struct qreg dst
, struct qreg src0
, struct qreg src1
)
354 struct qinst
*inst
= calloc(1, sizeof(*inst
));
356 inst
->qpu
= v3d_qpu_nop();
357 inst
->qpu
.alu
.add
.op
= op
;
368 vir_mul_inst(enum v3d_qpu_mul_op op
, struct qreg dst
, struct qreg src0
, struct qreg src1
)
370 struct qinst
*inst
= calloc(1, sizeof(*inst
));
372 inst
->qpu
= v3d_qpu_nop();
373 inst
->qpu
.alu
.mul
.op
= op
;
384 vir_branch_inst(enum v3d_qpu_branch_cond cond
, struct qreg src
)
386 struct qinst
*inst
= calloc(1, sizeof(*inst
));
388 inst
->qpu
= v3d_qpu_nop();
389 inst
->qpu
.type
= V3D_QPU_INSTR_TYPE_BRANCH
;
390 inst
->qpu
.branch
.cond
= cond
;
391 inst
->qpu
.branch
.msfign
= V3D_QPU_MSFIGN_NONE
;
392 inst
->qpu
.branch
.bdi
= V3D_QPU_BRANCH_DEST_REL
;
393 inst
->qpu
.branch
.ub
= true;
394 inst
->qpu
.branch
.bdu
= V3D_QPU_BRANCH_DEST_REL
;
396 inst
->dst
= vir_reg(QFILE_NULL
, 0);
404 vir_emit(struct v3d_compile
*c
, struct qinst
*inst
)
406 list_addtail(&inst
->link
, &c
->cur_block
->instructions
);
408 if (inst
->dst
.file
== QFILE_MAGIC
&&
409 inst
->dst
.index
== V3D_QPU_WADDR_VPM
)
413 /* Updates inst to write to a new temporary, emits it, and notes the def. */
415 vir_emit_def(struct v3d_compile
*c
, struct qinst
*inst
)
417 assert(inst
->dst
.file
== QFILE_NULL
);
419 inst
->dst
= vir_get_temp(c
);
421 if (inst
->dst
.file
== QFILE_TEMP
)
422 c
->defs
[inst
->dst
.index
] = inst
;
430 vir_emit_nondef(struct v3d_compile
*c
, struct qinst
*inst
)
432 if (inst
->dst
.file
== QFILE_TEMP
)
433 c
->defs
[inst
->dst
.index
] = NULL
;
441 vir_new_block(struct v3d_compile
*c
)
443 struct qblock
*block
= rzalloc(c
, struct qblock
);
445 list_inithead(&block
->instructions
);
447 block
->predecessors
= _mesa_set_create(block
,
449 _mesa_key_pointer_equal
);
451 block
->index
= c
->next_block_index
++;
457 vir_set_emit_block(struct v3d_compile
*c
, struct qblock
*block
)
459 c
->cur_block
= block
;
460 list_addtail(&block
->link
, &c
->blocks
);
464 vir_entry_block(struct v3d_compile
*c
)
466 return list_first_entry(&c
->blocks
, struct qblock
, link
);
470 vir_exit_block(struct v3d_compile
*c
)
472 return list_last_entry(&c
->blocks
, struct qblock
, link
);
476 vir_link_blocks(struct qblock
*predecessor
, struct qblock
*successor
)
478 _mesa_set_add(successor
->predecessors
, predecessor
);
479 if (predecessor
->successors
[0]) {
480 assert(!predecessor
->successors
[1]);
481 predecessor
->successors
[1] = successor
;
483 predecessor
->successors
[0] = successor
;
487 const struct v3d_compiler
*
488 v3d_compiler_init(const struct v3d_device_info
*devinfo
)
490 struct v3d_compiler
*compiler
= rzalloc(NULL
, struct v3d_compiler
);
494 compiler
->devinfo
= devinfo
;
496 if (!vir_init_reg_sets(compiler
)) {
497 ralloc_free(compiler
);
505 v3d_compiler_free(const struct v3d_compiler
*compiler
)
507 ralloc_free((void *)compiler
);
510 static struct v3d_compile
*
511 vir_compile_init(const struct v3d_compiler
*compiler
,
514 int program_id
, int variant_id
)
516 struct v3d_compile
*c
= rzalloc(NULL
, struct v3d_compile
);
518 c
->compiler
= compiler
;
519 c
->devinfo
= compiler
->devinfo
;
521 c
->program_id
= program_id
;
522 c
->variant_id
= variant_id
;
524 s
= nir_shader_clone(c
, s
);
527 list_inithead(&c
->blocks
);
528 vir_set_emit_block(c
, vir_new_block(c
));
530 c
->output_position_index
= -1;
531 c
->output_point_size_index
= -1;
532 c
->output_sample_mask_index
= -1;
534 c
->def_ht
= _mesa_hash_table_create(c
, _mesa_hash_pointer
,
535 _mesa_key_pointer_equal
);
541 v3d_lower_nir(struct v3d_compile
*c
)
543 struct nir_lower_tex_options tex_options
= {
544 .lower_rect
= false, /* XXX */
546 /* Apply swizzles to all samplers. */
547 .swizzle_result
= ~0,
550 /* Lower the format swizzle and (for 32-bit returns)
551 * ARB_texture_swizzle-style swizzle.
553 for (int i
= 0; i
< ARRAY_SIZE(c
->key
->tex
); i
++) {
554 for (int j
= 0; j
< 4; j
++)
555 tex_options
.swizzles
[i
][j
] = c
->key
->tex
[i
].swizzle
[j
];
558 NIR_PASS_V(c
->s
, nir_lower_tex
, &tex_options
);
562 v3d_lower_nir_late(struct v3d_compile
*c
)
564 NIR_PASS_V(c
->s
, v3d_nir_lower_io
, c
);
565 NIR_PASS_V(c
->s
, nir_lower_idiv
);
569 v3d_set_prog_data_uniforms(struct v3d_compile
*c
,
570 struct v3d_prog_data
*prog_data
)
572 int count
= c
->num_uniforms
;
573 struct v3d_uniform_list
*ulist
= &prog_data
->uniforms
;
575 ulist
->count
= count
;
576 ulist
->data
= ralloc_array(prog_data
, uint32_t, count
);
577 memcpy(ulist
->data
, c
->uniform_data
,
578 count
* sizeof(*ulist
->data
));
579 ulist
->contents
= ralloc_array(prog_data
, enum quniform_contents
, count
);
580 memcpy(ulist
->contents
, c
->uniform_contents
,
581 count
* sizeof(*ulist
->contents
));
584 /* Copy the compiler UBO range state to the compiled shader, dropping out
585 * arrays that were never referenced by an indirect load.
587 * (Note that QIR dead code elimination of an array access still leaves that
588 * array alive, though)
591 v3d_set_prog_data_ubo(struct v3d_compile
*c
,
592 struct v3d_prog_data
*prog_data
)
594 if (!c
->num_ubo_ranges
)
597 prog_data
->num_ubo_ranges
= 0;
598 prog_data
->ubo_ranges
= ralloc_array(prog_data
, struct v3d_ubo_range
,
600 for (int i
= 0; i
< c
->num_ubo_ranges
; i
++) {
601 if (!c
->ubo_range_used
[i
])
604 struct v3d_ubo_range
*range
= &c
->ubo_ranges
[i
];
605 prog_data
->ubo_ranges
[prog_data
->num_ubo_ranges
++] = *range
;
606 prog_data
->ubo_size
+= range
->size
;
609 if (prog_data
->ubo_size
) {
610 if (V3D_DEBUG
& V3D_DEBUG_SHADERDB
) {
611 fprintf(stderr
, "SHADER-DB: %s prog %d/%d: %d UBO uniforms\n",
612 vir_get_stage_name(c
),
613 c
->program_id
, c
->variant_id
,
614 prog_data
->ubo_size
/ 4);
620 v3d_set_prog_data(struct v3d_compile
*c
,
621 struct v3d_prog_data
*prog_data
)
623 v3d_set_prog_data_uniforms(c
, prog_data
);
624 v3d_set_prog_data_ubo(c
, prog_data
);
628 v3d_return_qpu_insts(struct v3d_compile
*c
, uint32_t *final_assembly_size
)
630 *final_assembly_size
= c
->qpu_inst_count
* sizeof(uint64_t);
632 uint64_t *qpu_insts
= malloc(*final_assembly_size
);
636 memcpy(qpu_insts
, c
->qpu_insts
, *final_assembly_size
);
638 vir_compile_destroy(c
);
643 uint64_t *v3d_compile_vs(const struct v3d_compiler
*compiler
,
644 struct v3d_vs_key
*key
,
645 struct v3d_vs_prog_data
*prog_data
,
647 int program_id
, int variant_id
,
648 uint32_t *final_assembly_size
)
650 struct v3d_compile
*c
= vir_compile_init(compiler
, &key
->base
, s
,
651 program_id
, variant_id
);
657 if (key
->clamp_color
)
658 NIR_PASS_V(c
->s
, nir_lower_clamp_color_outputs
);
660 if (key
->base
.ucp_enables
) {
661 NIR_PASS_V(c
->s
, nir_lower_clip_vs
, key
->base
.ucp_enables
);
662 NIR_PASS_V(c
->s
, nir_lower_io_to_scalar
,
666 /* Note: VS output scalarizing must happen after nir_lower_clip_vs. */
667 NIR_PASS_V(c
->s
, nir_lower_io_to_scalar
, nir_var_shader_out
);
669 v3d_lower_nir_late(c
);
670 v3d_optimize_nir(c
->s
);
671 NIR_PASS_V(c
->s
, nir_convert_from_ssa
, true);
675 v3d_set_prog_data(c
, &prog_data
->base
);
677 prog_data
->base
.num_inputs
= c
->num_inputs
;
679 /* The vertex data gets format converted by the VPM so that
680 * each attribute channel takes up a VPM column. Precompute
681 * the sizes for the shader record.
683 for (int i
= 0; i
< ARRAY_SIZE(prog_data
->vattr_sizes
); i
++) {
684 prog_data
->vattr_sizes
[i
] = c
->vattr_sizes
[i
];
685 prog_data
->vpm_input_size
+= c
->vattr_sizes
[i
];
688 /* Input/output segment size are in 8x32-bit multiples. */
689 prog_data
->vpm_input_size
= align(prog_data
->vpm_input_size
, 8) / 8;
690 prog_data
->vpm_output_size
= align(c
->num_vpm_writes
, 8) / 8;
692 prog_data
->uses_vid
= (s
->info
.system_values_read
&
693 (1ull << SYSTEM_VALUE_VERTEX_ID
));
694 prog_data
->uses_iid
= (s
->info
.system_values_read
&
695 (1ull << SYSTEM_VALUE_INSTANCE_ID
));
697 return v3d_return_qpu_insts(c
, final_assembly_size
);
701 v3d_set_fs_prog_data_inputs(struct v3d_compile
*c
,
702 struct v3d_fs_prog_data
*prog_data
)
704 prog_data
->base
.num_inputs
= c
->num_inputs
;
705 memcpy(prog_data
->input_slots
, c
->input_slots
,
706 c
->num_inputs
* sizeof(*c
->input_slots
));
708 memcpy(prog_data
->flat_shade_flags
, c
->flat_shade_flags
,
709 sizeof(c
->flat_shade_flags
));
710 memcpy(prog_data
->shade_model_flags
, c
->shade_model_flags
,
711 sizeof(c
->shade_model_flags
));
714 uint64_t *v3d_compile_fs(const struct v3d_compiler
*compiler
,
715 struct v3d_fs_key
*key
,
716 struct v3d_fs_prog_data
*prog_data
,
718 int program_id
, int variant_id
,
719 uint32_t *final_assembly_size
)
721 struct v3d_compile
*c
= vir_compile_init(compiler
, &key
->base
, s
,
722 program_id
, variant_id
);
728 if (key
->light_twoside
)
729 NIR_PASS_V(c
->s
, nir_lower_two_sided_color
);
731 if (key
->clamp_color
)
732 NIR_PASS_V(c
->s
, nir_lower_clamp_color_outputs
);
734 if (key
->alpha_test
) {
735 NIR_PASS_V(c
->s
, nir_lower_alpha_test
, key
->alpha_test_func
,
739 if (key
->base
.ucp_enables
)
740 NIR_PASS_V(c
->s
, nir_lower_clip_fs
, key
->base
.ucp_enables
);
742 /* Note: FS input scalarizing must happen after
743 * nir_lower_two_sided_color, which only handles a vec4 at a time.
745 NIR_PASS_V(c
->s
, nir_lower_io_to_scalar
, nir_var_shader_in
);
747 v3d_lower_nir_late(c
);
748 v3d_optimize_nir(c
->s
);
749 NIR_PASS_V(c
->s
, nir_convert_from_ssa
, true);
753 v3d_set_prog_data(c
, &prog_data
->base
);
754 v3d_set_fs_prog_data_inputs(c
, prog_data
);
755 prog_data
->writes_z
= (c
->s
->info
.outputs_written
&
756 (1 << FRAG_RESULT_DEPTH
));
757 prog_data
->discard
= c
->s
->info
.fs
.uses_discard
;
759 return v3d_return_qpu_insts(c
, final_assembly_size
);
763 vir_remove_instruction(struct v3d_compile
*c
, struct qinst
*qinst
)
765 if (qinst
->dst
.file
== QFILE_TEMP
)
766 c
->defs
[qinst
->dst
.index
] = NULL
;
768 list_del(&qinst
->link
);
773 vir_follow_movs(struct v3d_compile
*c
, struct qreg reg
)
778 while (reg.file == QFILE_TEMP &&
779 c->defs[reg.index] &&
780 (c->defs[reg.index]->op == QOP_MOV ||
781 c->defs[reg.index]->op == QOP_FMOV) &&
782 !c->defs[reg.index]->dst.pack &&
783 !c->defs[reg.index]->src[0].pack) {
784 reg = c->defs[reg.index]->src[0];
793 vir_compile_destroy(struct v3d_compile
*c
)
795 vir_for_each_block(block
, c
) {
796 while (!list_empty(&block
->instructions
)) {
797 struct qinst
*qinst
=
798 list_first_entry(&block
->instructions
,
800 vir_remove_instruction(c
, qinst
);
808 vir_uniform(struct v3d_compile
*c
,
809 enum quniform_contents contents
,
812 for (int i
= 0; i
< c
->num_uniforms
; i
++) {
813 if (c
->uniform_contents
[i
] == contents
&&
814 c
->uniform_data
[i
] == data
) {
815 return vir_reg(QFILE_UNIF
, i
);
819 uint32_t uniform
= c
->num_uniforms
++;
821 if (uniform
>= c
->uniform_array_size
) {
822 c
->uniform_array_size
= MAX2(MAX2(16, uniform
+ 1),
823 c
->uniform_array_size
* 2);
825 c
->uniform_data
= reralloc(c
, c
->uniform_data
,
827 c
->uniform_array_size
);
828 c
->uniform_contents
= reralloc(c
, c
->uniform_contents
,
829 enum quniform_contents
,
830 c
->uniform_array_size
);
833 c
->uniform_contents
[uniform
] = contents
;
834 c
->uniform_data
[uniform
] = data
;
836 return vir_reg(QFILE_UNIF
, uniform
);
840 vir_PF(struct v3d_compile
*c
, struct qreg src
, enum v3d_qpu_pf pf
)
842 struct qinst
*last_inst
= NULL
;
844 if (!list_empty(&c
->cur_block
->instructions
))
845 last_inst
= (struct qinst
*)c
->cur_block
->instructions
.prev
;
847 if (src
.file
!= QFILE_TEMP
||
848 !c
->defs
[src
.index
] ||
849 last_inst
!= c
->defs
[src
.index
]) {
850 /* XXX: Make the MOV be the appropriate type */
851 last_inst
= vir_MOV_dest(c
, vir_reg(QFILE_NULL
, 0), src
);
852 last_inst
= (struct qinst
*)c
->cur_block
->instructions
.prev
;
855 vir_set_pf(last_inst
, pf
);
858 #define OPTPASS(func) \
860 bool stage_progress = func(c); \
861 if (stage_progress) { \
863 if (print_opt_debug) { \
865 "VIR opt pass %2d: %s progress\n", \
868 /*XXX vir_validate(c);*/ \
873 vir_optimize(struct v3d_compile
*c
)
875 bool print_opt_debug
= false;
879 bool progress
= false;
881 OPTPASS(vir_opt_copy_propagate
);
882 OPTPASS(vir_opt_dead_code
);
892 vir_get_stage_name(struct v3d_compile
*c
)
894 if (c
->vs_key
&& c
->vs_key
->is_coord
)
895 return "MESA_SHADER_COORD";
897 return gl_shader_stage_name(c
->s
->stage
);