nir/opt_vectorize: Add a callback for filtering of vectorizing.
[mesa.git] / src / gallium / drivers / r600 / sfn / sfn_shader_tess_eval.cpp
1 #include "sfn_shader_tess_eval.h"
2 #include "tgsi/tgsi_from_mesa.h"
3
4 namespace r600 {
5
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
22 bool TEvalShaderFromNir::do_process_inputs(nir_variable *input)
23 {
24 if (input->data.location == VARYING_SLOT_POS ||
25 input->data.location == VARYING_SLOT_PSIZ ||
26 input->data.location == VARYING_SLOT_CLIP_DIST0 ||
27 input->data.location == VARYING_SLOT_CLIP_DIST1 ||
28 (input->data.location >= VARYING_SLOT_VAR0 &&
29 input->data.location <= VARYING_SLOT_VAR31) ||
30 (input->data.location >= VARYING_SLOT_TEX0 &&
31 input->data.location <= VARYING_SLOT_TEX7) ||
32 (input->data.location >= VARYING_SLOT_PATCH0 &&
33 input->data.location <= VARYING_SLOT_TESS_MAX)) {
34
35 r600_shader_io& io = sh_info().input[input->data.driver_location];
36 tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>( input->data.location),
37 true, &io.name, &io.sid);
38 ++sh_info().ninput;
39 return true;
40 }
41
42 return false;
43
44 }
45
46 bool TEvalShaderFromNir::scan_sysvalue_access(nir_instr *instr)
47 {
48 if (instr->type != nir_instr_type_intrinsic)
49 return true;
50
51 auto ir = nir_instr_as_intrinsic(instr);
52
53 switch (ir->intrinsic) {
54 case nir_intrinsic_load_tess_coord:
55 m_sv_values.set(es_tess_coord);
56 break;
57 case nir_intrinsic_load_primitive_id:
58 m_sv_values.set(es_primitive_id);
59 break;
60 case nir_intrinsic_load_tcs_rel_patch_id_r600:
61 m_sv_values.set(es_rel_patch_id);
62 break;
63 default:
64 ;
65 }
66 return true;
67 }
68
69 bool TEvalShaderFromNir::do_allocate_reserved_registers()
70 {
71 if (m_sv_values.test(es_tess_coord)) {
72 m_reserved_registers = 1;
73 auto gpr = new GPRValue(0,0);
74 gpr->set_as_input();
75 m_tess_coord[0].reset(gpr);
76 gpr = new GPRValue(0,1);
77 gpr->set_as_input();
78 m_tess_coord[1].reset(gpr);
79 }
80
81 if (m_sv_values.test(es_rel_patch_id)) {
82 m_reserved_registers = 1;
83 auto gpr = new GPRValue(0,2);
84 gpr->set_as_input();
85 m_rel_patch_id.reset(gpr);
86 }
87
88 if (m_sv_values.test(es_primitive_id) ||
89 m_key.vs.as_gs_a) {
90 m_reserved_registers = 1;
91 auto gpr = new GPRValue(0,3);
92 gpr->set_as_input();
93 m_primitive_id.reset(gpr);
94 if (m_key.vs.as_gs_a)
95 inject_register(0, 3, m_primitive_id, false);
96 }
97 set_reserved_registers(m_reserved_registers);
98 return true;
99 }
100
101 bool TEvalShaderFromNir::load_tess_z_coord(nir_intrinsic_instr* instr)
102 {
103 if (m_tess_coord[2])
104 return load_preloaded_value(instr->dest, 2, m_tess_coord[2]);
105
106 m_tess_coord[2] = from_nir(instr->dest, 2);
107 emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], Value::one_f, m_tess_coord[0], {alu_last_instr, alu_write, alu_src1_neg}));
108 emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2], m_tess_coord[1], {alu_last_instr, alu_write, alu_src1_neg}));
109 return true;
110 }
111
112 bool TEvalShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr)
113 {
114 switch (instr->intrinsic) {
115 case nir_intrinsic_load_tess_coord:
116 return load_preloaded_value(instr->dest, 0, m_tess_coord[0]) &&
117 load_preloaded_value(instr->dest, 1, m_tess_coord[1]) &&
118 load_tess_z_coord(instr);
119 case nir_intrinsic_load_primitive_id:
120 return load_preloaded_value(instr->dest, 0, m_primitive_id);
121 case nir_intrinsic_load_tcs_rel_patch_id_r600:
122 return load_preloaded_value(instr->dest, 0, m_rel_patch_id);
123 default:
124 return false;
125 }
126 }
127
128
129 bool TEvalShaderFromNir::do_process_outputs(nir_variable *output)
130 {
131 return m_export_processor->do_process_outputs(output);
132 }
133
134 bool TEvalShaderFromNir::do_emit_store_deref(const nir_variable *out_var, nir_intrinsic_instr* instr)
135 {
136 return m_export_processor->store_deref(out_var, instr);
137 }
138
139 void TEvalShaderFromNir::do_finalize()
140 {
141 m_export_processor->finalize_exports();
142 }
143
144
145 bool TEvalShaderFromNir::emit_load_tess_coord(nir_intrinsic_instr* instr)
146 {
147 bool result = load_preloaded_value(instr->dest, 0, m_tess_coord[0]) &&
148 load_preloaded_value(instr->dest, 1, m_tess_coord[1]);
149
150 m_tess_coord[2] = from_nir(instr->dest, 2);
151
152
153 emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2],
154 m_tess_coord[0], {alu_last_instr, alu_write, alu_src0_neg}));
155 emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2],
156 m_tess_coord[1], {alu_last_instr, alu_write, alu_src0_neg}));
157 return result;
158 }
159
160 }