mirror of https://gitlab.freedesktop.org/mesa/mesa
nir: Keep track of cross-invocation mesh shader output access.
On some implementations eg. AMD RDNA2 the driver can generate a more optimal code path knowing whether outputs are indexed using the local invocation index or not. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Marcin Ślusarz <marcin.slusarz@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16736>
This commit is contained in:
parent
cd14431b8c
commit
112a856813
|
@ -36,6 +36,17 @@ src_is_invocation_id(const nir_src *src)
|
|||
nir_intrinsic_load_invocation_id;
|
||||
}
|
||||
|
||||
static bool
|
||||
src_is_local_invocation_index(const nir_src *src)
|
||||
{
|
||||
assert(src->is_ssa);
|
||||
if (src->ssa->parent_instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
|
||||
return nir_instr_as_intrinsic(src->ssa->parent_instr)->intrinsic ==
|
||||
nir_intrinsic_load_local_invocation_index;
|
||||
}
|
||||
|
||||
static void
|
||||
get_deref_info(nir_shader *shader, nir_variable *var, nir_deref_instr *deref,
|
||||
bool *cross_invocation, bool *indirect)
|
||||
|
@ -53,7 +64,10 @@ get_deref_info(nir_shader *shader, nir_variable *var, nir_deref_instr *deref,
|
|||
/* Vertex index is the outermost array index. */
|
||||
if (is_arrayed) {
|
||||
assert((*p)->deref_type == nir_deref_type_array);
|
||||
*cross_invocation = !src_is_invocation_id(&(*p)->arr.index);
|
||||
if (shader->info.stage == MESA_SHADER_TESS_CTRL)
|
||||
*cross_invocation = !src_is_invocation_id(&(*p)->arr.index);
|
||||
else if (shader->info.stage == MESA_SHADER_MESH)
|
||||
*cross_invocation = !src_is_local_invocation_index(&(*p)->arr.index);
|
||||
p++;
|
||||
}
|
||||
|
||||
|
@ -154,6 +168,8 @@ set_io_mask(nir_shader *shader, nir_variable *var, int offset, int len,
|
|||
}
|
||||
}
|
||||
|
||||
if (cross_invocation && shader->info.stage == MESA_SHADER_MESH)
|
||||
shader->info.mesh.ms_cross_invocation_output_access |= bitfield;
|
||||
|
||||
if (var->data.fb_fetch_output) {
|
||||
shader->info.outputs_read |= bitfield;
|
||||
|
@ -592,6 +608,13 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
|
|||
!src_is_invocation_id(nir_get_io_arrayed_index_src(instr)))
|
||||
shader->info.tess.tcs_cross_invocation_outputs_read |= slot_mask;
|
||||
|
||||
/* NV_mesh_shader: mesh shaders can load their outputs. */
|
||||
if (shader->info.stage == MESA_SHADER_MESH &&
|
||||
(instr->intrinsic == nir_intrinsic_load_per_vertex_output ||
|
||||
instr->intrinsic == nir_intrinsic_load_per_primitive_output) &&
|
||||
!src_is_local_invocation_index(nir_get_io_arrayed_index_src(instr)))
|
||||
shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
|
||||
|
||||
if (shader->info.stage == MESA_SHADER_FRAGMENT &&
|
||||
nir_intrinsic_io_semantics(instr).fb_fetch_output)
|
||||
shader->info.fs.uses_fbfetch_output = true;
|
||||
|
@ -614,6 +637,12 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader,
|
|||
}
|
||||
}
|
||||
|
||||
if (shader->info.stage == MESA_SHADER_MESH &&
|
||||
(instr->intrinsic == nir_intrinsic_store_per_vertex_output ||
|
||||
instr->intrinsic == nir_intrinsic_store_per_primitive_output) &&
|
||||
!src_is_local_invocation_index(nir_get_io_arrayed_index_src(instr)))
|
||||
shader->info.mesh.ms_cross_invocation_output_access |= slot_mask;
|
||||
|
||||
if (shader->info.stage == MESA_SHADER_FRAGMENT &&
|
||||
nir_intrinsic_io_semantics(instr).dual_source_blend_index)
|
||||
shader->info.fs.color_is_dual_source = true;
|
||||
|
|
|
@ -505,6 +505,11 @@ typedef struct shader_info {
|
|||
|
||||
/* Applies to MESH. */
|
||||
struct {
|
||||
/* Bit mask of MS outputs that are used
|
||||
* with an index that is NOT the local invocation index.
|
||||
*/
|
||||
uint64_t ms_cross_invocation_output_access;
|
||||
|
||||
uint16_t max_vertices_out;
|
||||
uint16_t max_primitives_out;
|
||||
uint16_t primitive_type; /* GL_POINTS, GL_LINES or GL_TRIANGLES. */
|
||||
|
|
Loading…
Reference in New Issue