r600/sfn: Handle indirect access to GS input arrays
nir_intrinsic_load_per_vertex_input has two source values, indirect access
by using the first value is already handled, but accessing arrays with
the second index was missing but became relevant with handling most IO
optimizations with nir_opt_varyings.
Fixes: 37ae4df3e4 ("glsl: remove most IO optimizations that are replaced by nir_opt_varyings")
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36488>
This commit is contained in:
@@ -275,6 +275,36 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class LowerGSArrayInput : public NirLowerInstruction {
|
||||
bool filter(const nir_instr *instr) const override
|
||||
{
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
|
||||
auto intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_load_per_vertex_input)
|
||||
return false;
|
||||
|
||||
return nir_intrinsic_io_semantics(intr).num_slots != 1;
|
||||
}
|
||||
|
||||
nir_def *lower(nir_instr *instr) override
|
||||
{
|
||||
auto intr = nir_instr_as_intrinsic(instr);
|
||||
auto vbase = nir_r600_indirect_vertex_at_index(b, 32, intr->src[0].ssa);
|
||||
auto new_addr =
|
||||
nir_iadd(b, vbase, nir_ishl(b, intr->src[1].ssa, nir_imm_int(b, 2)));
|
||||
auto io_semantics = nir_intrinsic_io_semantics(intr);
|
||||
return nir_load_r600_indirect_per_vertex_input(b,
|
||||
intr->num_components,
|
||||
intr->def.bit_size,
|
||||
new_addr,
|
||||
nir_imm_zero(b, 1, 32),
|
||||
.base = nir_intrinsic_base(intr),
|
||||
.range = nir_intrinsic_range(intr),
|
||||
.io_semantics = io_semantics);
|
||||
}
|
||||
};
|
||||
} // namespace r600
|
||||
|
||||
static nir_intrinsic_op
|
||||
@@ -367,6 +397,13 @@ r600_lower_clipvertex_to_clipdist(nir_shader *sh, pipe_stream_output_info& so_in
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool
|
||||
r600_lower_gs_input_array(nir_shader *sh)
|
||||
{
|
||||
assert(sh->info.stage == MESA_SHADER_GEOMETRY);
|
||||
return r600::LowerGSArrayInput().run(sh);
|
||||
}
|
||||
|
||||
static bool
|
||||
r600_nir_lower_atomics(nir_shader *shader)
|
||||
{
|
||||
@@ -913,6 +950,8 @@ r600_lower_and_optimize_nir(nir_shader *sh,
|
||||
if (r600_is_last_vertex_stage(sh, *key))
|
||||
r600_lower_clipvertex_to_clipdist(sh, *so_info);
|
||||
|
||||
if (sh->info.stage == MESA_SHADER_GEOMETRY)
|
||||
NIR_PASS(_, sh, r600_lower_gs_input_array);
|
||||
if (sh->info.stage == MESA_SHADER_TESS_CTRL ||
|
||||
sh->info.stage == MESA_SHADER_TESS_EVAL ||
|
||||
(sh->info.stage == MESA_SHADER_VERTEX && key->vs.as_ls)) {
|
||||
|
||||
@@ -88,11 +88,8 @@ GeometryShader::process_store_output(nir_intrinsic_instr *instr)
|
||||
bool
|
||||
GeometryShader::process_load_input(nir_intrinsic_instr *instr)
|
||||
{
|
||||
auto location = static_cast<gl_varying_slot>(nir_intrinsic_io_semantics(instr).location);
|
||||
auto index = nir_src_as_const_value(instr->src[1]);
|
||||
assert(index);
|
||||
|
||||
auto driver_location = nir_intrinsic_base(instr) + index->u32;
|
||||
auto location =
|
||||
static_cast<gl_varying_slot>(nir_intrinsic_io_semantics(instr).location);
|
||||
|
||||
if (location == VARYING_SLOT_POS || location == VARYING_SLOT_PSIZ ||
|
||||
location == VARYING_SLOT_FOGC || location == VARYING_SLOT_CLIP_VERTEX ||
|
||||
@@ -103,10 +100,21 @@ GeometryShader::process_load_input(nir_intrinsic_instr *instr)
|
||||
(location >= VARYING_SLOT_VAR0 && location <= VARYING_SLOT_VAR31) ||
|
||||
(location >= VARYING_SLOT_TEX0 && location <= VARYING_SLOT_TEX7)) {
|
||||
|
||||
add_input_at(location, driver_location);
|
||||
if (nir_intrinsic_io_semantics(instr).num_slots == 1) {
|
||||
auto index = nir_src_as_const_value(instr->src[1]);
|
||||
auto driver_location = nir_intrinsic_base(instr) + index->u32;
|
||||
add_input_at(location, driver_location);
|
||||
} else {
|
||||
auto base = nir_intrinsic_base(instr);
|
||||
unsigned range = nir_intrinsic_range(instr);
|
||||
for (unsigned i = 0; i < range; ++i) {
|
||||
auto driver_location = base + i;
|
||||
auto array_location = static_cast<gl_varying_slot>(location + i);
|
||||
add_input_at(array_location, driver_location);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user