• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_process_outputs(nir_variable * output)45 bool TcsShaderFromNir::do_process_outputs(nir_variable *output)
46 {
47    unsigned name, sid;
48 
49    tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>(output->data.location),
50                                 true, &name, &sid);
51 
52    auto& io = sh_info().output[sh_info().noutput++];
53    io.name = name;
54    io.write_mask = ((1 << output->type->components()) - 1)
55                    << output->data.location_frac;
56    return true;
57 }
58 
do_allocate_reserved_registers()59 bool TcsShaderFromNir::do_allocate_reserved_registers()
60 {
61    if (m_sv_values.test(es_primitive_id)) {
62       m_reserved_registers = 1;
63       auto gpr = new GPRValue(0,0);
64       gpr->set_as_input();
65       m_primitive_id.reset(gpr);
66    }
67 
68    if (m_sv_values.test(es_invocation_id)) {
69       m_reserved_registers = 1;
70       auto gpr = new GPRValue(0,2);
71       gpr->set_as_input();
72       m_invocation_id.reset(gpr);
73    }
74 
75    if (m_sv_values.test(es_rel_patch_id)) {
76       m_reserved_registers = 1;
77       auto gpr = new GPRValue(0,1);
78       gpr->set_as_input();
79       m_rel_patch_id.reset(gpr);
80    }
81 
82    if (m_sv_values.test(es_tess_factor_base)) {
83       m_reserved_registers = 1;
84       auto gpr = new GPRValue(0,3);
85       gpr->set_as_input();
86       m_tess_factor_base.reset(gpr);
87    }
88 
89    set_reserved_registers(m_reserved_registers);
90 
91    return true;
92 }
93 
emit_intrinsic_instruction_override(nir_intrinsic_instr * instr)94 bool TcsShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr)
95 {
96    switch (instr->intrinsic) {
97    case nir_intrinsic_load_tcs_rel_patch_id_r600:
98       return load_preloaded_value(instr->dest, 0, m_rel_patch_id);
99    case nir_intrinsic_load_invocation_id:
100       return load_preloaded_value(instr->dest, 0, m_invocation_id);
101    case nir_intrinsic_load_primitive_id:
102       return load_preloaded_value(instr->dest, 0, m_primitive_id);
103    case nir_intrinsic_load_tcs_tess_factor_base_r600:
104       return load_preloaded_value(instr->dest, 0, m_tess_factor_base);
105    case nir_intrinsic_store_tf_r600:
106       return store_tess_factor(instr);
107    default:
108       return false;
109    }
110 }
111 
store_tess_factor(nir_intrinsic_instr * instr)112 bool TcsShaderFromNir::store_tess_factor(nir_intrinsic_instr* instr)
113 {
114    const GPRVector::Swizzle& swizzle = (instr->src[0].ssa->num_components == 4) ?
115             GPRVector::Swizzle({0, 1, 2, 3}) : GPRVector::Swizzle({0, 1, 7, 7});
116    auto val = vec_from_nir_with_fetch_constant(instr->src[0],
117          (1 << instr->src[0].ssa->num_components) - 1, swizzle);
118    emit_instruction(new GDSStoreTessFactor(val));
119    return true;
120 }
121 
122 }
123