mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
r600/sfn: Add tesselation shaders
Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>
This commit is contained in:
parent
d77b81ce50
commit
b6d4452661
8 changed files with 421 additions and 6 deletions
|
|
@ -144,6 +144,10 @@ CXX_SOURCES = \
|
|||
sfn/sfn_shader_fragment.h \
|
||||
sfn/sfn_shader_geometry.cpp \
|
||||
sfn/sfn_shader_geometry.h \
|
||||
sfn/sfn_shader_tcs.cpp \
|
||||
sfn/sfn_shader_tcs.h \
|
||||
sfn/sfn_shader_tess_eval.cpp \
|
||||
sfn/sfn_shader_tess_eval.h \
|
||||
sfn/sfn_shader_vertex.cpp \
|
||||
sfn/sfn_shader_vertex.h \
|
||||
sfn/sfn_shaderio.cpp \
|
||||
|
|
|
|||
|
|
@ -161,6 +161,10 @@ files_r600 = files(
|
|||
'sfn/sfn_shader_fragment.h',
|
||||
'sfn/sfn_shader_geometry.cpp',
|
||||
'sfn/sfn_shader_geometry.h',
|
||||
'sfn/sfn_shader_tcs.cpp',
|
||||
'sfn/sfn_shader_tcs.h',
|
||||
'sfn/sfn_shader_tess_eval.cpp',
|
||||
'sfn/sfn_shader_tess_eval.h',
|
||||
'sfn/sfn_shader_vertex.cpp',
|
||||
'sfn/sfn_shader_vertex.h',
|
||||
'sfn/sfn_shaderio.cpp',
|
||||
|
|
|
|||
|
|
@ -1180,6 +1180,24 @@ struct pipe_resource *r600_resource_create_common(struct pipe_screen *screen,
|
|||
}
|
||||
}
|
||||
|
||||
const struct nir_shader_compiler_options r600_nir_fs_options = {
|
||||
.fuse_ffma = true,
|
||||
.lower_scmp = true,
|
||||
.lower_flrp32 = true,
|
||||
.lower_flrp64 = true,
|
||||
.lower_fpow = true,
|
||||
.lower_fdiv = true,
|
||||
.lower_idiv = true,
|
||||
.lower_fmod = true,
|
||||
.lower_doubles_options = nir_lower_fp64_full_software,
|
||||
.lower_int64_options = 0,
|
||||
.lower_extract_byte = true,
|
||||
.lower_extract_word = true,
|
||||
.max_unroll_iterations = 32,
|
||||
.lower_all_io_to_temps = true,
|
||||
.vectorize_io = true
|
||||
};
|
||||
|
||||
const struct nir_shader_compiler_options r600_nir_options = {
|
||||
.fuse_ffma = true,
|
||||
.lower_scmp = true,
|
||||
|
|
@ -1200,13 +1218,17 @@ const struct nir_shader_compiler_options r600_nir_options = {
|
|||
.has_umul24 = true,
|
||||
};
|
||||
|
||||
|
||||
static const void *
|
||||
r600_get_compiler_options(struct pipe_screen *screen,
|
||||
enum pipe_shader_ir ir,
|
||||
enum pipe_shader_type shader)
|
||||
{
|
||||
assert(ir == PIPE_SHADER_IR_NIR);
|
||||
return &r600_nir_options;
|
||||
if (shader == PIPE_SHADER_FRAGMENT)
|
||||
return &r600_nir_fs_options;
|
||||
else
|
||||
return &r600_nir_options;
|
||||
}
|
||||
|
||||
bool r600_common_screen_init(struct r600_common_screen *rscreen,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
#include "sfn_shader_fragment.h"
|
||||
#include "sfn_shader_geometry.h"
|
||||
#include "sfn_shader_compute.h"
|
||||
#include "sfn_shader_tcs.h"
|
||||
#include "sfn_shader_tess_eval.h"
|
||||
#include "sfn_nir_lower_fs_out_to_vector.h"
|
||||
#include "sfn_ir_to_assembly.h"
|
||||
|
||||
|
|
@ -62,6 +64,13 @@ bool ShaderFromNir::lower(const nir_shader *shader, r600_pipe_shader *pipe_shade
|
|||
case MESA_SHADER_VERTEX:
|
||||
impl.reset(new VertexShaderFromNir(pipe_shader, *sel, key, gs_shader));
|
||||
break;
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
sfn_log << SfnLog::trans << "Start TCS\n";
|
||||
impl.reset(new TcsShaderFromNir(pipe_shader, *sel, key));
|
||||
break;
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
sfn_log << SfnLog::trans << "Start TESS_EVAL\n";
|
||||
impl.reset(new TEvalShaderFromNir(pipe_shader, *sel, key, gs_shader));
|
||||
break;
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
sfn_log << SfnLog::trans << "Start GS\n";
|
||||
|
|
@ -585,13 +594,31 @@ int r600_shader_from_nir(struct r600_context *rctx,
|
|||
NIR_PASS_V(sel->nir, r600_lower_fs_out_to_vector);
|
||||
|
||||
if (sel->nir->info.stage == MESA_SHADER_TESS_CTRL ||
|
||||
sel->nir->info.stage == MESA_SHADER_TESS_EVAL)
|
||||
NIR_PASS_V(sel->nir, nir_lower_io, nir_var_shader_in, r600_glsl_type_size,
|
||||
nir_lower_io_lower_64bit_to_32);
|
||||
|
||||
if (sel->nir->info.stage == MESA_SHADER_TESS_CTRL)
|
||||
(sel->nir->info.stage == MESA_SHADER_VERTEX && key->vs.as_ls)) {
|
||||
NIR_PASS_V(sel->nir, nir_lower_io, nir_var_shader_out, r600_glsl_type_size,
|
||||
nir_lower_io_lower_64bit_to_32);
|
||||
NIR_PASS_V(sel->nir, r600_lower_tess_io, (pipe_prim_type)key->tcs.prim_mode);
|
||||
}
|
||||
|
||||
if (sel->nir->info.stage == MESA_SHADER_TESS_CTRL ||
|
||||
sel->nir->info.stage == MESA_SHADER_TESS_EVAL) {
|
||||
NIR_PASS_V(sel->nir, nir_lower_io, nir_var_shader_in, r600_glsl_type_size,
|
||||
nir_lower_io_lower_64bit_to_32);
|
||||
}
|
||||
|
||||
if (sel->nir->info.stage == MESA_SHADER_TESS_CTRL ||
|
||||
sel->nir->info.stage == MESA_SHADER_TESS_EVAL ||
|
||||
(sel->nir->info.stage == MESA_SHADER_VERTEX && key->vs.as_ls)) {
|
||||
auto prim_type = sel->nir->info.stage == MESA_SHADER_TESS_CTRL ?
|
||||
key->tcs.prim_mode : sel->nir->info.tess.primitive_mode;
|
||||
NIR_PASS_V(sel->nir, r600_lower_tess_io, static_cast<pipe_prim_type>(prim_type));
|
||||
}
|
||||
|
||||
|
||||
if (sel->nir->info.stage == MESA_SHADER_TESS_CTRL)
|
||||
NIR_PASS_V(sel->nir, r600_append_tcs_TF_emission,
|
||||
(pipe_prim_type)key->tcs.prim_mode);
|
||||
|
||||
|
||||
const nir_function *func = reinterpret_cast<const nir_function *>(exec_list_get_head_const(&sel->nir->functions));
|
||||
bool optimize = func->impl->registers.length() == 0 && !has_saturate(func);
|
||||
|
|
|
|||
121
src/gallium/drivers/r600/sfn/sfn_shader_tcs.cpp
Normal file
121
src/gallium/drivers/r600/sfn/sfn_shader_tcs.cpp
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#include "sfn_shader_tcs.h"
|
||||
#include "sfn_instruction_gds.h"
|
||||
#include "tgsi/tgsi_from_mesa.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
TcsShaderFromNir::TcsShaderFromNir(r600_pipe_shader *sh,
|
||||
r600_pipe_shader_selector& sel,
|
||||
const r600_shader_key& key):
|
||||
ShaderFromNirProcessor (PIPE_SHADER_TESS_CTRL, sel, sh->shader,
|
||||
sh->scratch_space_needed),
|
||||
m_reserved_registers(0)
|
||||
{
|
||||
sh_info().tcs_prim_mode = key.tcs.prim_mode;
|
||||
}
|
||||
|
||||
bool TcsShaderFromNir::scan_sysvalue_access(nir_instr *instr)
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return true;
|
||||
|
||||
auto intr = nir_instr_as_intrinsic(instr);
|
||||
|
||||
switch (intr->intrinsic) {
|
||||
case nir_intrinsic_load_primitive_id:
|
||||
m_sv_values.set(es_primitive_id);
|
||||
break;
|
||||
case nir_intrinsic_load_invocation_id:
|
||||
m_sv_values.set(es_invocation_id);
|
||||
break;
|
||||
case nir_intrinsic_load_tcs_rel_patch_id_r600:
|
||||
m_sv_values.set(es_rel_patch_id);
|
||||
break;
|
||||
case nir_intrinsic_load_tcs_tess_factor_base_r600:
|
||||
m_sv_values.set(es_tess_factor_base);
|
||||
break;
|
||||
default:
|
||||
|
||||
;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TcsShaderFromNir::do_process_outputs(nir_variable *output)
|
||||
{
|
||||
unsigned name, sid;
|
||||
|
||||
tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>(output->data.location),
|
||||
true, &name, &sid);
|
||||
|
||||
auto& io = sh_info().output[sh_info().noutput++];
|
||||
io.name = name;
|
||||
io.write_mask = ((1 << output->type->components()) - 1)
|
||||
<< output->data.location_frac;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TcsShaderFromNir::allocate_reserved_registers()
|
||||
{
|
||||
if (m_sv_values.test(es_primitive_id)) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,0);
|
||||
gpr->set_as_input();
|
||||
m_primitive_id.reset(gpr);
|
||||
}
|
||||
|
||||
if (m_sv_values.test(es_invocation_id)) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,2);
|
||||
gpr->set_as_input();
|
||||
m_invocation_id.reset(gpr);
|
||||
}
|
||||
|
||||
if (m_sv_values.test(es_rel_patch_id)) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,1);
|
||||
gpr->set_as_input();
|
||||
m_rel_patch_id.reset(gpr);
|
||||
}
|
||||
|
||||
if (m_sv_values.test(es_tess_factor_base)) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,3);
|
||||
gpr->set_as_input();
|
||||
m_tess_factor_base.reset(gpr);
|
||||
}
|
||||
|
||||
set_reserved_registers(m_reserved_registers);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TcsShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr)
|
||||
{
|
||||
switch (instr->intrinsic) {
|
||||
case nir_intrinsic_load_tcs_rel_patch_id_r600:
|
||||
return load_preloaded_value(instr->dest, 0, m_rel_patch_id);
|
||||
case nir_intrinsic_load_invocation_id:
|
||||
return load_preloaded_value(instr->dest, 0, m_invocation_id);
|
||||
case nir_intrinsic_load_primitive_id:
|
||||
return load_preloaded_value(instr->dest, 0, m_primitive_id);
|
||||
case nir_intrinsic_load_tcs_tess_factor_base_r600:
|
||||
return load_preloaded_value(instr->dest, 0, m_tess_factor_base);
|
||||
case nir_intrinsic_store_tf_r600:
|
||||
return store_tess_factor(instr);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TcsShaderFromNir::store_tess_factor(nir_intrinsic_instr* instr)
|
||||
{
|
||||
const GPRVector::Swizzle& swizzle = (instr->src[0].ssa->num_components == 4) ?
|
||||
GPRVector::Swizzle({0, 1, 2, 3}) : GPRVector::Swizzle({0, 1, 7, 7});
|
||||
std::unique_ptr<GPRVector> val(vec_from_nir_with_fetch_constant(instr->src[0],
|
||||
0xf, swizzle));
|
||||
emit_instruction(new GDSStoreTessFactor(*val));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
37
src/gallium/drivers/r600/sfn/sfn_shader_tcs.h
Normal file
37
src/gallium/drivers/r600/sfn/sfn_shader_tcs.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef TCSSHADERFROMNIR_H
|
||||
#define TCSSHADERFROMNIR_H
|
||||
|
||||
#include "sfn_shader_base.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
class TcsShaderFromNir : public ShaderFromNirProcessor
|
||||
{
|
||||
public:
|
||||
TcsShaderFromNir(r600_pipe_shader *sh, r600_pipe_shader_selector& sel, const r600_shader_key& key);
|
||||
bool scan_sysvalue_access(nir_instr *instr) override;
|
||||
|
||||
private:
|
||||
bool allocate_reserved_registers() override;
|
||||
bool emit_intrinsic_instruction_override(nir_intrinsic_instr* instr) override;
|
||||
bool store_tess_factor(nir_intrinsic_instr* instr);
|
||||
|
||||
bool do_process_inputs(nir_variable *input) override { return true;}
|
||||
bool do_process_outputs(nir_variable *output) override;
|
||||
bool do_emit_load_deref(const nir_variable *in_var, nir_intrinsic_instr* instr) override { return true;}
|
||||
bool do_emit_store_deref(const nir_variable *out_var, nir_intrinsic_instr* instr) override { return true;}
|
||||
void do_finalize() override {}
|
||||
|
||||
int m_reserved_registers;
|
||||
PValue m_patch_id;
|
||||
PValue m_rel_patch_id;
|
||||
PValue m_invocation_id;
|
||||
PValue m_primitive_id;
|
||||
PValue m_tess_factor_base;
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // TCSSHADERFROMNIR_H
|
||||
159
src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.cpp
Normal file
159
src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.cpp
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#include "sfn_shader_tess_eval.h"
|
||||
#include "tgsi/tgsi_from_mesa.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
TEvalShaderFromNir::TEvalShaderFromNir(r600_pipe_shader *sh, r600_pipe_shader_selector& sel,
|
||||
const r600_shader_key& key, r600_shader *gs_shader):
|
||||
VertexStage(PIPE_SHADER_TESS_EVAL, sel, sh->shader,
|
||||
sh->scratch_space_needed),
|
||||
m_reserved_registers(0),
|
||||
m_key(key)
|
||||
|
||||
{
|
||||
sh->shader.tes_as_es = key.tes.as_es;
|
||||
if (key.tes.as_es)
|
||||
m_export_processor.reset(new VertexStageExportForGS(*this, gs_shader));
|
||||
else
|
||||
m_export_processor.reset(new VertexStageExportForFS(*this, &sel.so, sh, key));
|
||||
}
|
||||
|
||||
bool TEvalShaderFromNir::do_process_inputs(nir_variable *input)
|
||||
{
|
||||
if (input->data.location == VARYING_SLOT_POS ||
|
||||
input->data.location == VARYING_SLOT_PSIZ ||
|
||||
input->data.location == VARYING_SLOT_CLIP_DIST0 ||
|
||||
input->data.location == VARYING_SLOT_CLIP_DIST1 ||
|
||||
(input->data.location >= VARYING_SLOT_VAR0 &&
|
||||
input->data.location <= VARYING_SLOT_VAR31) ||
|
||||
(input->data.location >= VARYING_SLOT_TEX0 &&
|
||||
input->data.location <= VARYING_SLOT_TEX7) ||
|
||||
(input->data.location >= VARYING_SLOT_PATCH0 &&
|
||||
input->data.location <= VARYING_SLOT_TESS_MAX)) {
|
||||
|
||||
r600_shader_io& io = sh_info().input[input->data.driver_location];
|
||||
tgsi_get_gl_varying_semantic(static_cast<gl_varying_slot>( input->data.location),
|
||||
true, &io.name, &io.sid);
|
||||
++sh_info().ninput;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool TEvalShaderFromNir::scan_sysvalue_access(nir_instr *instr)
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return true;
|
||||
|
||||
auto ir = nir_instr_as_intrinsic(instr);
|
||||
|
||||
switch (ir->intrinsic) {
|
||||
case nir_intrinsic_load_tess_coord:
|
||||
m_sv_values.set(es_tess_coord);
|
||||
break;
|
||||
case nir_intrinsic_load_primitive_id:
|
||||
m_sv_values.set(es_primitive_id);
|
||||
break;
|
||||
case nir_intrinsic_load_tcs_rel_patch_id_r600:
|
||||
m_sv_values.set(es_rel_patch_id);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TEvalShaderFromNir::allocate_reserved_registers()
|
||||
{
|
||||
if (m_sv_values.test(es_tess_coord)) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,0);
|
||||
gpr->set_as_input();
|
||||
m_tess_coord[0].reset(gpr);
|
||||
gpr = new GPRValue(0,1);
|
||||
gpr->set_as_input();
|
||||
m_tess_coord[1].reset(gpr);
|
||||
}
|
||||
|
||||
if (m_sv_values.test(es_rel_patch_id)) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,2);
|
||||
gpr->set_as_input();
|
||||
m_rel_patch_id.reset(gpr);
|
||||
}
|
||||
|
||||
if (m_sv_values.test(es_primitive_id) ||
|
||||
m_key.vs.as_gs_a) {
|
||||
m_reserved_registers = 1;
|
||||
auto gpr = new GPRValue(0,3);
|
||||
gpr->set_as_input();
|
||||
m_primitive_id.reset(gpr);
|
||||
if (m_key.vs.as_gs_a)
|
||||
inject_register(0, 3, m_primitive_id, false);
|
||||
}
|
||||
set_reserved_registers(m_reserved_registers);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TEvalShaderFromNir::load_tess_z_coord(nir_intrinsic_instr* instr)
|
||||
{
|
||||
if (m_tess_coord[2])
|
||||
return load_preloaded_value(instr->dest, 2, m_tess_coord[2]);
|
||||
|
||||
m_tess_coord[2] = from_nir(instr->dest, 2);
|
||||
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}));
|
||||
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}));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TEvalShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr)
|
||||
{
|
||||
switch (instr->intrinsic) {
|
||||
case nir_intrinsic_load_tess_coord:
|
||||
return load_preloaded_value(instr->dest, 0, m_tess_coord[0]) &&
|
||||
load_preloaded_value(instr->dest, 1, m_tess_coord[1]) &&
|
||||
load_tess_z_coord(instr);
|
||||
case nir_intrinsic_load_primitive_id:
|
||||
return load_preloaded_value(instr->dest, 0, m_primitive_id);
|
||||
case nir_intrinsic_load_tcs_rel_patch_id_r600:
|
||||
return load_preloaded_value(instr->dest, 0, m_rel_patch_id);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TEvalShaderFromNir::do_process_outputs(nir_variable *output)
|
||||
{
|
||||
return m_export_processor->do_process_outputs(output);
|
||||
}
|
||||
|
||||
bool TEvalShaderFromNir::do_emit_store_deref(const nir_variable *out_var, nir_intrinsic_instr* instr)
|
||||
{
|
||||
return m_export_processor->store_deref(out_var, instr);
|
||||
}
|
||||
|
||||
void TEvalShaderFromNir::do_finalize()
|
||||
{
|
||||
m_export_processor->finalize_exports();
|
||||
}
|
||||
|
||||
|
||||
bool TEvalShaderFromNir::emit_load_tess_coord(nir_intrinsic_instr* instr)
|
||||
{
|
||||
bool result = load_preloaded_value(instr->dest, 0, m_tess_coord[0]) &&
|
||||
load_preloaded_value(instr->dest, 1, m_tess_coord[1]);
|
||||
|
||||
m_tess_coord[2] = from_nir(instr->dest, 2);
|
||||
|
||||
|
||||
emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2],
|
||||
m_tess_coord[0], {alu_last_instr, alu_write, alu_src0_neg}));
|
||||
emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2],
|
||||
m_tess_coord[1], {alu_last_instr, alu_write, alu_src0_neg}));
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
41
src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.h
Normal file
41
src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#ifndef TEVALSHADERFROMNIR_H
|
||||
#define TEVALSHADERFROMNIR_H
|
||||
|
||||
#include "sfn_shader_base.h"
|
||||
#include "sfn_vertexstageexport.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
class TEvalShaderFromNir : public VertexStage
|
||||
{
|
||||
public:
|
||||
TEvalShaderFromNir(r600_pipe_shader *sh, r600_pipe_shader_selector& sel,
|
||||
const r600_shader_key& key, r600_shader *gs_shader);
|
||||
bool scan_sysvalue_access(nir_instr *instr) override;
|
||||
PValue primitive_id() override {return m_primitive_id;}
|
||||
private:
|
||||
bool allocate_reserved_registers() override;
|
||||
bool emit_intrinsic_instruction_override(nir_intrinsic_instr* instr) override;
|
||||
bool emit_load_tess_coord(nir_intrinsic_instr* instr);
|
||||
bool load_tess_z_coord(nir_intrinsic_instr* instr);
|
||||
|
||||
bool do_process_inputs(nir_variable *input) override;
|
||||
bool do_process_outputs(nir_variable *output) override;
|
||||
bool do_emit_load_deref(const nir_variable *in_var, nir_intrinsic_instr* instr) override { return true;}
|
||||
bool do_emit_store_deref(const nir_variable *out_var, nir_intrinsic_instr* instr) override;
|
||||
void do_finalize() override;
|
||||
|
||||
|
||||
unsigned m_reserved_registers;
|
||||
PValue m_tess_coord[3];
|
||||
PValue m_rel_patch_id;
|
||||
PValue m_primitive_id;
|
||||
|
||||
std::unique_ptr<VertexStageExportBase> m_export_processor;
|
||||
const r600_shader_key& m_key;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif // TEVALSHADERFROMNIR_H
|
||||
Loading…
Add table
Reference in a new issue