mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 09:38:07 +02:00
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:
parent
9c8d8cfa07
commit
39543f6b5c
2 changed files with 54 additions and 7 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue