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