mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
radv: export multi view index as layer after lowering io
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40982>
This commit is contained in:
parent
8e74c0020e
commit
ae2213fa6d
2 changed files with 34 additions and 91 deletions
|
|
@ -10,77 +10,53 @@
|
|||
#include "nir_builder.h"
|
||||
#include "radv_nir.h"
|
||||
|
||||
static nir_variable *
|
||||
find_layer_out_var(nir_shader *nir)
|
||||
static void
|
||||
export_multiview(nir_builder *b)
|
||||
{
|
||||
nir_variable *var = nir_find_variable_with_location(nir, nir_var_shader_out, VARYING_SLOT_LAYER);
|
||||
if (var != NULL)
|
||||
return var;
|
||||
nir_io_semantics io_sem = {
|
||||
.location = VARYING_SLOT_LAYER,
|
||||
.num_slots = 1,
|
||||
.no_varying = true,
|
||||
};
|
||||
|
||||
var = nir_variable_create(nir, nir_var_shader_out, glsl_int_type(), "layer id");
|
||||
var->data.location = VARYING_SLOT_LAYER;
|
||||
var->data.interpolation = INTERP_MODE_NONE;
|
||||
nir_store_output(b, nir_load_view_index(b), nir_imm_int(b, 0), .component = 0, .src_type = nir_type_int32,
|
||||
.io_semantics = io_sem);
|
||||
|
||||
return var;
|
||||
b->shader->info.outputs_written |= VARYING_BIT_LAYER;
|
||||
}
|
||||
|
||||
static bool
|
||||
export_multiview_per_emit(nir_builder *b, nir_intrinsic_instr *intr, void *unused)
|
||||
{
|
||||
if (intr->intrinsic != nir_intrinsic_emit_vertex_with_counter)
|
||||
return false;
|
||||
|
||||
b->cursor = nir_before_instr(&intr->instr);
|
||||
export_multiview(b);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
radv_nir_export_multiview(nir_shader *nir)
|
||||
{
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||
bool progress = false;
|
||||
|
||||
nir_builder b = nir_builder_create(impl);
|
||||
|
||||
/* This pass is not suitable for mesh shaders, because it can't know the mapping between API mesh
|
||||
* shader invocations and output primitives. Needs to be handled in ac_nir_lower_ngg.
|
||||
*/
|
||||
assert(nir->info.stage == MESA_SHADER_VERTEX || nir->info.stage == MESA_SHADER_TESS_EVAL ||
|
||||
nir->info.stage == MESA_SHADER_GEOMETRY);
|
||||
|
||||
/* Iterate in reverse order since there should be only one deref store to POS after
|
||||
* lower_io_to_temporaries for vertex shaders and inject the layer there. For geometry shaders,
|
||||
* the layer is injected right before every emit_vertex_with_counter.
|
||||
*/
|
||||
nir_variable *layer = NULL;
|
||||
nir_foreach_block_reverse (block, impl) {
|
||||
nir_foreach_instr_reverse (instr, block) {
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
continue;
|
||||
/* The shader shouldn't write gl_Layer itself. */
|
||||
assert(!(nir->info.outputs_written & VARYING_BIT_LAYER));
|
||||
|
||||
if (nir->info.stage == MESA_SHADER_GEOMETRY) {
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_emit_vertex_with_counter)
|
||||
continue;
|
||||
if (nir->info.stage == MESA_SHADER_GEOMETRY) {
|
||||
/* For geometry shaders, the layer is injected right before every emit_vertex_with_counter. */
|
||||
return nir_shader_intrinsics_pass(nir, export_multiview_per_emit, nir_metadata_control_flow, NULL);
|
||||
} else {
|
||||
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||
|
||||
b.cursor = nir_before_instr(instr);
|
||||
} else {
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_store_deref)
|
||||
continue;
|
||||
nir_builder b = nir_builder_at(nir_after_impl(impl));
|
||||
export_multiview(&b);
|
||||
|
||||
nir_variable *var = nir_intrinsic_get_var(intr, 0);
|
||||
if (var->data.mode != nir_var_shader_out || var->data.location != VARYING_SLOT_POS)
|
||||
continue;
|
||||
|
||||
b.cursor = nir_after_instr(instr);
|
||||
}
|
||||
|
||||
if (!layer)
|
||||
layer = find_layer_out_var(nir);
|
||||
|
||||
nir_store_var(&b, layer, nir_load_view_index(&b), 1);
|
||||
|
||||
/* Update outputs_written to reflect that the pass added a new output. */
|
||||
nir->info.outputs_written |= VARYING_BIT_LAYER;
|
||||
|
||||
progress = true;
|
||||
if (nir->info.stage == MESA_SHADER_VERTEX)
|
||||
break;
|
||||
}
|
||||
if (nir->info.stage == MESA_SHADER_VERTEX && progress)
|
||||
break;
|
||||
return nir_progress(true, impl, nir_metadata_control_flow);
|
||||
}
|
||||
|
||||
return nir_progress(progress, impl, nir_metadata_control_flow);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1211,17 +1211,6 @@ static const mesa_shader_stage graphics_shader_order[] = {
|
|||
MESA_SHADER_FRAGMENT,
|
||||
};
|
||||
|
||||
static void
|
||||
radv_link_vs(struct radv_shader_stage *vs_stage, struct radv_shader_stage *next_stage,
|
||||
const struct radv_graphics_state_key *gfx_state)
|
||||
{
|
||||
assert(vs_stage->nir->info.stage == MESA_SHADER_VERTEX);
|
||||
|
||||
if (radv_should_export_multiview(vs_stage, gfx_state)) {
|
||||
NIR_PASS(_, vs_stage->nir, radv_nir_export_multiview);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
radv_link_tcs(struct radv_shader_stage *tcs_stage, struct radv_shader_stage *tes_stage,
|
||||
const struct radv_graphics_state_key *gfx_state)
|
||||
|
|
@ -1236,28 +1225,6 @@ radv_link_tcs(struct radv_shader_stage *tcs_stage, struct radv_shader_stage *tes
|
|||
merge_tess_info(&tes_stage->nir->info, &tcs_stage->nir->info);
|
||||
}
|
||||
|
||||
static void
|
||||
radv_link_tes(struct radv_shader_stage *tes_stage, struct radv_shader_stage *next_stage,
|
||||
const struct radv_graphics_state_key *gfx_state)
|
||||
{
|
||||
assert(tes_stage->nir->info.stage == MESA_SHADER_TESS_EVAL);
|
||||
|
||||
if (radv_should_export_multiview(tes_stage, gfx_state)) {
|
||||
NIR_PASS(_, tes_stage->nir, radv_nir_export_multiview);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
radv_link_gs(struct radv_shader_stage *gs_stage, struct radv_shader_stage *fs_stage,
|
||||
const struct radv_graphics_state_key *gfx_state)
|
||||
{
|
||||
assert(gs_stage->nir->info.stage == MESA_SHADER_GEOMETRY);
|
||||
|
||||
if (radv_should_export_multiview(gs_stage, gfx_state)) {
|
||||
NIR_PASS(_, gs_stage->nir, radv_nir_export_multiview);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
radv_pipeline_needs_noop_fs(struct radv_graphics_pipeline *pipeline, const struct radv_graphics_state_key *gfx_state)
|
||||
{
|
||||
|
|
@ -1286,16 +1253,13 @@ radv_graphics_shaders_link(const struct radv_device *device, const struct radv_g
|
|||
|
||||
switch (s) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
radv_link_vs(&stages[s], next_stage, gfx_state);
|
||||
break;
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
radv_link_tcs(&stages[s], next_stage, gfx_state);
|
||||
break;
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
radv_link_tes(&stages[s], next_stage, gfx_state);
|
||||
break;
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
radv_link_gs(&stages[s], next_stage, gfx_state);
|
||||
break;
|
||||
case MESA_SHADER_TASK:
|
||||
break;
|
||||
|
|
@ -2671,6 +2635,9 @@ radv_graphics_shaders_compile(struct radv_device *device, struct vk_pipeline_cac
|
|||
BITSET_TEST(stages[i].nir->info.system_values_read, SYSTEM_VALUE_DRAW_ID))
|
||||
radv_nir_lower_draw_id_to_zero(stages[i].nir);
|
||||
|
||||
if (i != MESA_SHADER_MESH && radv_should_export_multiview(&stages[i], gfx_state))
|
||||
NIR_PASS(_, stages[i].nir, radv_nir_export_multiview);
|
||||
|
||||
uint64_t remove_as_varying = 0;
|
||||
uint64_t remove_as_sysval = 0;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue