nvk: Move a bunch of codegen-specific lowering to helpers

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26197>
This commit is contained in:
Faith Ekstrand 2023-11-14 10:53:52 -06:00 committed by Marge Bot
parent c3a44f6264
commit 7f8fbacb8a
3 changed files with 91 additions and 78 deletions

View file

@ -5,6 +5,9 @@
#include "nvk_physical_device.h"
#include "nvk_shader.h"
#include "nir.h"
#include "nir_builder.h"
#include "nv50_ir_driver.h"
uint64_t
@ -48,3 +51,87 @@ nvk_cg_nir_options(const struct nvk_physical_device *pdev,
enum pipe_shader_type p_stage = pipe_shader_type_from_mesa(stage);
return nv50_ir_nir_shader_compiler_options(pdev->info.chipset, p_stage);
}
static nir_variable *
find_or_create_input(nir_builder *b, const struct glsl_type *type,
const char *name, unsigned location)
{
nir_foreach_shader_in_variable(in, b->shader) {
if (in->data.location == location)
return in;
}
nir_variable *in = nir_variable_create(b->shader, nir_var_shader_in,
type, name);
in->data.location = location;
if (glsl_type_is_integer(type))
in->data.interpolation = INTERP_MODE_FLAT;
return in;
}
static bool
lower_fragcoord_instr(nir_builder *b, nir_instr *instr, UNUSED void *_data)
{
assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
nir_variable *var;
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
b->cursor = nir_before_instr(&intrin->instr);
nir_def *val;
switch (intrin->intrinsic) {
case nir_intrinsic_load_frag_coord:
var = find_or_create_input(b, glsl_vec4_type(),
"gl_FragCoord",
VARYING_SLOT_POS);
val = nir_load_var(b, var);
break;
case nir_intrinsic_load_point_coord:
var = find_or_create_input(b, glsl_vector_type(GLSL_TYPE_FLOAT, 2),
"gl_PointCoord",
VARYING_SLOT_PNTC);
val = nir_load_var(b, var);
break;
case nir_intrinsic_load_sample_pos:
var = find_or_create_input(b, glsl_vec4_type(),
"gl_FragCoord",
VARYING_SLOT_POS);
val = nir_ffract(b, nir_trim_vector(b, nir_load_var(b, var), 2));
break;
case nir_intrinsic_load_layer_id:
var = find_or_create_input(b, glsl_int_type(),
"gl_Layer", VARYING_SLOT_LAYER);
val = nir_load_var(b, var);
break;
default:
return false;
}
nir_def_rewrite_uses(&intrin->def, val);
return true;
}
void
nvk_cg_preprocess_nir(nir_shader *nir)
{
NIR_PASS(_, nir, nir_split_struct_vars, nir_var_function_temp);
NIR_PASS(_, nir, nir_lower_vars_to_ssa);
NIR_PASS(_, nir, nir_split_var_copies);
NIR_PASS(_, nir, nir_lower_vars_to_ssa);
NIR_PASS(_, nir, nir_lower_global_vars_to_local);
NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
NIR_PASS(_, nir, nir_lower_system_values);
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
NIR_PASS(_, nir, nir_shader_instructions_pass, lower_fragcoord_instr,
nir_metadata_block_index | nir_metadata_dominance, NULL);
}
}

View file

@ -246,70 +246,6 @@ lower_load_global_constant_offset_instr(nir_builder *b,
return true;
}
static nir_variable *
find_or_create_input(nir_builder *b, const struct glsl_type *type,
const char *name, unsigned location)
{
nir_foreach_shader_in_variable(in, b->shader) {
if (in->data.location == location)
return in;
}
nir_variable *in = nir_variable_create(b->shader, nir_var_shader_in,
type, name);
in->data.location = location;
if (glsl_type_is_integer(type))
in->data.interpolation = INTERP_MODE_FLAT;
return in;
}
static bool
lower_fragcoord_instr(nir_builder *b, nir_instr *instr, UNUSED void *_data)
{
assert(b->shader->info.stage == MESA_SHADER_FRAGMENT);
nir_variable *var;
if (instr->type != nir_instr_type_intrinsic)
return false;
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
b->cursor = nir_before_instr(&intrin->instr);
nir_def *val;
switch (intrin->intrinsic) {
case nir_intrinsic_load_frag_coord:
var = find_or_create_input(b, glsl_vec4_type(),
"gl_FragCoord",
VARYING_SLOT_POS);
val = nir_load_var(b, var);
break;
case nir_intrinsic_load_point_coord:
var = find_or_create_input(b, glsl_vector_type(GLSL_TYPE_FLOAT, 2),
"gl_PointCoord",
VARYING_SLOT_PNTC);
val = nir_load_var(b, var);
break;
case nir_intrinsic_load_sample_pos:
var = find_or_create_input(b, glsl_vec4_type(),
"gl_FragCoord",
VARYING_SLOT_POS);
val = nir_ffract(b, nir_trim_vector(b, nir_load_var(b, var), 2));
break;
case nir_intrinsic_load_layer_id:
var = find_or_create_input(b, glsl_int_type(),
"gl_Layer", VARYING_SLOT_LAYER);
val = nir_load_var(b, var);
break;
default:
return false;
}
nir_def_rewrite_uses(&intrin->def, val);
return true;
}
static int
count_location_slots(const struct glsl_type *type, bool bindless)
{
@ -473,6 +409,8 @@ nvk_shader_stage_to_nir(struct nvk_device *dev,
if (use_nak(dev->pdev, nir->info.stage))
nak_preprocess_nir(nir, NULL);
else
nvk_cg_preprocess_nir(nir);
vk_pipeline_cache_add_nir(cache, stage_sha1, sizeof(stage_sha1), nir);
@ -498,21 +436,7 @@ nvk_lower_nir(struct nvk_device *dev, nir_shader *nir,
{
struct nvk_physical_device *pdev = nvk_device_physical(dev);
NIR_PASS(_, nir, nir_split_struct_vars, nir_var_function_temp);
NIR_PASS(_, nir, nir_lower_vars_to_ssa);
NIR_PASS(_, nir, nir_split_var_copies);
NIR_PASS(_, nir, nir_lower_vars_to_ssa);
NIR_PASS(_, nir, nir_lower_global_vars_to_local);
NIR_PASS(_, nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
NIR_PASS(_, nir, nir_lower_system_values);
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
if (!use_nak(pdev, nir->info.stage)) {
NIR_PASS(_, nir, nir_shader_instructions_pass, lower_fragcoord_instr,
nir_metadata_block_index | nir_metadata_dominance, NULL);
}
NIR_PASS(_, nir, nir_lower_input_attachments,
&(nir_input_attachment_options) {
.use_fragcoord_sysval = use_nak(pdev, nir->info.stage),

View file

@ -165,4 +165,6 @@ const nir_shader_compiler_options *
nvk_cg_nir_options(const struct nvk_physical_device *pdev,
gl_shader_stage stage);
void nvk_cg_preprocess_nir(nir_shader *nir);
#endif