1 #include "sfn_shader_tess_eval.h"
2 #include "tgsi/tgsi_from_mesa.h"
3
4 namespace r600 {
5
TEvalShaderFromNir(r600_pipe_shader * sh,r600_pipe_shader_selector & sel,const r600_shader_key & key,r600_shader * gs_shader,enum chip_class chip_class)6 TEvalShaderFromNir::TEvalShaderFromNir(r600_pipe_shader *sh, r600_pipe_shader_selector& sel,
7 const r600_shader_key& key, r600_shader *gs_shader,
8 enum chip_class chip_class):
9 VertexStage(PIPE_SHADER_TESS_EVAL, sel, sh->shader,
10 sh->scratch_space_needed, chip_class, key.tes.first_atomic_counter),
11 m_reserved_registers(0),
12 m_key(key)
13
14 {
15 sh->shader.tes_as_es = key.tes.as_es;
16 if (key.tes.as_es)
17 m_export_processor.reset(new VertexStageExportForGS(*this, gs_shader));
18 else
19 m_export_processor.reset(new VertexStageExportForFS(*this, &sel.so, sh, key));
20 }
21
scan_sysvalue_access(nir_instr * instr)22 bool TEvalShaderFromNir::scan_sysvalue_access(nir_instr *instr)
23 {
24 if (instr->type != nir_instr_type_intrinsic)
25 return true;
26
27 auto ir = nir_instr_as_intrinsic(instr);
28
29 switch (ir->intrinsic) {
30 case nir_intrinsic_load_tess_coord_r600:
31 m_sv_values.set(es_tess_coord);
32 break;
33 case nir_intrinsic_load_primitive_id:
34 m_sv_values.set(es_primitive_id);
35 break;
36 case nir_intrinsic_load_tcs_rel_patch_id_r600:
37 m_sv_values.set(es_rel_patch_id);
38 break;
39 case nir_intrinsic_store_output:
40 m_export_processor->scan_store_output(ir);
41 break;
42 default:
43 ;
44 }
45 return true;
46 }
47
emit_shader_start()48 void TEvalShaderFromNir::emit_shader_start()
49 {
50 m_export_processor->emit_shader_start();
51 }
52
do_allocate_reserved_registers()53 bool TEvalShaderFromNir::do_allocate_reserved_registers()
54 {
55 if (m_sv_values.test(es_tess_coord)) {
56 m_reserved_registers = 1;
57 auto gpr = new GPRValue(0,0);
58 gpr->set_as_input();
59 m_tess_coord[0].reset(gpr);
60 gpr = new GPRValue(0,1);
61 gpr->set_as_input();
62 m_tess_coord[1].reset(gpr);
63 }
64
65 if (m_sv_values.test(es_rel_patch_id)) {
66 m_reserved_registers = 1;
67 auto gpr = new GPRValue(0,2);
68 gpr->set_as_input();
69 m_rel_patch_id.reset(gpr);
70 }
71
72 if (m_sv_values.test(es_primitive_id) ||
73 m_key.vs.as_gs_a) {
74 m_reserved_registers = 1;
75 auto gpr = new GPRValue(0,3);
76 gpr->set_as_input();
77 m_primitive_id.reset(gpr);
78 if (m_key.vs.as_gs_a)
79 inject_register(0, 3, m_primitive_id, false);
80 }
81 set_reserved_registers(m_reserved_registers);
82 return true;
83 }
84
emit_intrinsic_instruction_override(nir_intrinsic_instr * instr)85 bool TEvalShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr)
86 {
87 switch (instr->intrinsic) {
88 case nir_intrinsic_load_tess_coord_r600:
89 return load_preloaded_value(instr->dest, 0, m_tess_coord[0]) &&
90 load_preloaded_value(instr->dest, 1, m_tess_coord[1]);
91 case nir_intrinsic_load_primitive_id:
92 return load_preloaded_value(instr->dest, 0, m_primitive_id);
93 case nir_intrinsic_load_tcs_rel_patch_id_r600:
94 return load_preloaded_value(instr->dest, 0, m_rel_patch_id);
95 case nir_intrinsic_store_output:
96 return m_export_processor->store_output(instr);
97 default:
98 return false;
99 }
100 }
101
do_finalize()102 void TEvalShaderFromNir::do_finalize()
103 {
104 m_export_processor->finalize_exports();
105 }
106
107
emit_load_tess_coord(nir_intrinsic_instr * instr)108 bool TEvalShaderFromNir::emit_load_tess_coord(nir_intrinsic_instr* instr)
109 {
110 bool result = load_preloaded_value(instr->dest, 0, m_tess_coord[0]) &&
111 load_preloaded_value(instr->dest, 1, m_tess_coord[1]);
112
113 m_tess_coord[2] = from_nir(instr->dest, 2);
114
115
116 emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2],
117 m_tess_coord[0], {alu_last_instr, alu_write, alu_src0_neg}));
118 emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2],
119 m_tess_coord[1], {alu_last_instr, alu_write, alu_src0_neg}));
120 return result;
121 }
122
123 }
124