1 #include "sfn_shader_tcs.h"
2 #include "sfn_instruction_gds.h"
3 #include "tgsi/tgsi_from_mesa.h"
4 
5 namespace r600 {
6 
TcsShaderFromNir(r600_pipe_shader * sh,r600_pipe_shader_selector & sel,const r600_shader_key & key,enum chip_class chip_class)7 TcsShaderFromNir::TcsShaderFromNir(r600_pipe_shader *sh,
8                                    r600_pipe_shader_selector& sel,
9                                    const r600_shader_key& key,
10                                    enum chip_class chip_class):
11    ShaderFromNirProcessor (PIPE_SHADER_TESS_CTRL, sel, sh->shader,
12                            sh->scratch_space_needed, chip_class, key.tcs.first_atomic_counter),
13    m_reserved_registers(0)
14 {
15    sh_info().tcs_prim_mode = key.tcs.prim_mode;
16 }
17 
scan_sysvalue_access(nir_instr * instr)18 bool TcsShaderFromNir::scan_sysvalue_access(nir_instr *instr)
19 {
20    if (instr->type != nir_instr_type_intrinsic)
21       return true;
22 
23    auto intr = nir_instr_as_intrinsic(instr);
24 
25    switch (intr->intrinsic) {
26    case nir_intrinsic_load_primitive_id:
27       m_sv_values.set(es_primitive_id);
28       break;
29    case nir_intrinsic_load_invocation_id:
30       m_sv_values.set(es_invocation_id);
31       break;
32    case nir_intrinsic_load_tcs_rel_patch_id_r600:
33       m_sv_values.set(es_rel_patch_id);
34       break;
35    case nir_intrinsic_load_tcs_tess_factor_base_r600:
36       m_sv_values.set(es_tess_factor_base);
37       break;
38    default:
39 
40       ;
41    }
42    return true;
43 }
44 
do_allocate_reserved_registers()45 bool TcsShaderFromNir::do_allocate_reserved_registers()
46 {
47    if (m_sv_values.test(es_primitive_id)) {
48       m_reserved_registers = 1;
49       auto gpr = new GPRValue(0,0);
50       gpr->set_as_input();
51       m_primitive_id.reset(gpr);
52    }
53 
54    if (m_sv_values.test(es_invocation_id)) {
55       m_reserved_registers = 1;
56       auto gpr = new GPRValue(0,2);
57       gpr->set_as_input();
58       m_invocation_id.reset(gpr);
59    }
60 
61    if (m_sv_values.test(es_rel_patch_id)) {
62       m_reserved_registers = 1;
63       auto gpr = new GPRValue(0,1);
64       gpr->set_as_input();
65       m_rel_patch_id.reset(gpr);
66    }
67 
68    if (m_sv_values.test(es_tess_factor_base)) {
69       m_reserved_registers = 1;
70       auto gpr = new GPRValue(0,3);
71       gpr->set_as_input();
72       m_tess_factor_base.reset(gpr);
73    }
74 
75    set_reserved_registers(m_reserved_registers);
76 
77    return true;
78 }
79 
emit_intrinsic_instruction_override(nir_intrinsic_instr * instr)80 bool TcsShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr)
81 {
82    switch (instr->intrinsic) {
83    case nir_intrinsic_load_tcs_rel_patch_id_r600:
84       return load_preloaded_value(instr->dest, 0, m_rel_patch_id);
85    case nir_intrinsic_load_invocation_id:
86       return load_preloaded_value(instr->dest, 0, m_invocation_id);
87    case nir_intrinsic_load_primitive_id:
88       return load_preloaded_value(instr->dest, 0, m_primitive_id);
89    case nir_intrinsic_load_tcs_tess_factor_base_r600:
90       return load_preloaded_value(instr->dest, 0, m_tess_factor_base);
91    case nir_intrinsic_store_tf_r600:
92       return store_tess_factor(instr);
93    default:
94       return false;
95    }
96 }
97 
store_tess_factor(nir_intrinsic_instr * instr)98 bool TcsShaderFromNir::store_tess_factor(nir_intrinsic_instr* instr)
99 {
100    const GPRVector::Swizzle& swizzle = (instr->src[0].ssa->num_components == 4) ?
101             GPRVector::Swizzle({0, 1, 2, 3}) : GPRVector::Swizzle({0, 1, 7, 7});
102    auto val = vec_from_nir_with_fetch_constant(instr->src[0],
103          (1 << instr->src[0].ssa->num_components) - 1, swizzle);
104    emit_instruction(new GDSStoreTessFactor(val));
105    return true;
106 }
107 
108 }
109