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 
do_process_inputs(nir_variable * input)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 
scan_sysvalue_access(nir_instr * instr)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 
do_allocate_reserved_registers()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 
load_tess_z_coord(nir_intrinsic_instr * instr)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 
emit_intrinsic_instruction_override(nir_intrinsic_instr * instr)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 
do_process_outputs(nir_variable * output)129 bool TEvalShaderFromNir::do_process_outputs(nir_variable *output)
130 {
131    return m_export_processor->do_process_outputs(output);
132 }
133 
do_emit_store_deref(const nir_variable * out_var,nir_intrinsic_instr * instr)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 
do_finalize()139 void TEvalShaderFromNir::do_finalize()
140 {
141    m_export_processor->finalize_exports();
142 }
143 
144 
emit_load_tess_coord(nir_intrinsic_instr * instr)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 }
161