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