nir/propagate_invariant: add invariant_prim option

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11035>
This commit is contained in:
Rhys Perry 2021-01-13 15:50:52 +00:00 committed by Marge Bot
parent 7144f33802
commit ea68d4a676
6 changed files with 31 additions and 33 deletions

View file

@ -241,28 +241,6 @@ radv_compiler_debug(void *private_data, enum radv_compiler_debug_level level, co
&debug_data->module->base, 0, 0, "radv", message);
}
static void
mark_geom_invariant(nir_shader *nir)
{
nir_foreach_shader_out_variable(var, nir)
{
switch (var->data.location) {
case VARYING_SLOT_POS:
case VARYING_SLOT_PSIZ:
case VARYING_SLOT_CLIP_DIST0:
case VARYING_SLOT_CLIP_DIST1:
case VARYING_SLOT_CULL_DIST0:
case VARYING_SLOT_CULL_DIST1:
case VARYING_SLOT_TESS_LEVEL_OUTER:
case VARYING_SLOT_TESS_LEVEL_INNER:
var->data.invariant = true;
break;
default:
break;
}
}
}
static nir_ssa_def *
convert_pointer_to_64(nir_builder *b, const struct radv_physical_device *pdev, nir_ssa_def *ptr)
{
@ -560,12 +538,8 @@ radv_shader_compile_to_nir(struct radv_device *device, struct vk_shader_module *
NIR_PASS_V(nir, nir_lower_global_vars_to_local);
NIR_PASS_V(nir, nir_lower_vars_to_ssa);
if (device->instance->debug_flags & RADV_DEBUG_INVARIANT_GEOM &&
stage != MESA_SHADER_FRAGMENT) {
mark_geom_invariant(nir);
}
NIR_PASS_V(nir, nir_propagate_invariant);
NIR_PASS_V(nir, nir_propagate_invariant,
device->instance->debug_flags & RADV_DEBUG_INVARIANT_GEOM);
NIR_PASS_V(nir, nir_lower_system_values);
NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);

View file

@ -362,7 +362,7 @@ preprocess_nir(nir_shader *nir,
nir_var_shader_out | nir_var_system_value | nir_var_mem_shared,
NULL);
NIR_PASS_V(nir, nir_propagate_invariant);
NIR_PASS_V(nir, nir_propagate_invariant, false);
NIR_PASS_V(nir, nir_lower_io_to_temporaries,
nir_shader_get_entrypoint(nir), true, false);

View file

@ -4317,7 +4317,7 @@ void nir_inline_uniforms(nir_shader *shader, unsigned num_uniforms,
const uint32_t *uniform_values,
const uint16_t *uniform_dw_offsets);
bool nir_propagate_invariant(nir_shader *shader);
bool nir_propagate_invariant(nir_shader *shader, bool invariant_prim);
void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, nir_shader *shader);
void nir_lower_deref_copy_instr(struct nir_builder *b,

View file

@ -188,12 +188,36 @@ propagate_invariant_impl(nir_function_impl *impl, struct set *invariants)
return progress;
}
/* If invariant_prim=true, this pass considers all geometry-affecting
* outputs as invariant. Doing this works around a common class of application
* bugs appearing as flickering.
*/
bool
nir_propagate_invariant(nir_shader *shader)
nir_propagate_invariant(nir_shader *shader, bool invariant_prim)
{
/* Hash set of invariant things */
struct set *invariants = _mesa_pointer_set_create(NULL);
if (shader->info.stage != MESA_SHADER_FRAGMENT && invariant_prim) {
nir_foreach_shader_out_variable(var, shader) {
switch (var->data.location) {
case VARYING_SLOT_POS:
case VARYING_SLOT_PSIZ:
case VARYING_SLOT_CLIP_DIST0:
case VARYING_SLOT_CLIP_DIST1:
case VARYING_SLOT_CULL_DIST0:
case VARYING_SLOT_CULL_DIST1:
case VARYING_SLOT_TESS_LEVEL_OUTER:
case VARYING_SLOT_TESS_LEVEL_INNER:
if (!var->data.invariant)
_mesa_set_add(invariants, var);
break;
default:
break;
}
}
}
bool progress = false;
nir_foreach_function(function, shader) {
if (function->impl && propagate_invariant_impl(function->impl, invariants))

View file

@ -168,7 +168,7 @@ tu_spirv_to_nir(struct tu_device *dev,
nir_var_shader_in | nir_var_shader_out | nir_var_system_value | nir_var_mem_shared,
NULL);
NIR_PASS_V(nir, nir_propagate_invariant);
NIR_PASS_V(nir, nir_propagate_invariant, false);
NIR_PASS_V(nir, nir_lower_global_vars_to_local);
NIR_PASS_V(nir, nir_split_var_copies);

View file

@ -248,7 +248,7 @@ anv_shader_compile_to_nir(struct anv_device *device,
nir_var_shader_in | nir_var_shader_out | nir_var_system_value,
NULL);
NIR_PASS_V(nir, nir_propagate_invariant);
NIR_PASS_V(nir, nir_propagate_invariant, false);
NIR_PASS_V(nir, nir_lower_io_to_temporaries,
nir_shader_get_entrypoint(nir), true, false);