nir/lower_mediump_vars: Don't lower mediump shared vars with atomic access.
I don't know of any GPUs doing 16-bit atomic accesses, nor do I know of anybody wanting that in shaders. But deqp has GLES CTS cases that set mediump on shared variables, so just skip lowering for those vars. Reviewed-by: Matt Turner <mattst88@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18452>
This commit is contained in:
@@ -387,11 +387,14 @@ is_mediump_or_lowp(unsigned precision)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
try_lower_mediump_var(nir_variable *var, nir_variable_mode modes)
|
try_lower_mediump_var(nir_variable *var, nir_variable_mode modes, struct set *set)
|
||||||
{
|
{
|
||||||
if (!(var->data.mode & modes) || !is_mediump_or_lowp(var->data.precision))
|
if (!(var->data.mode & modes) || !is_mediump_or_lowp(var->data.precision))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (set && _mesa_set_search(set, var))
|
||||||
|
return false;
|
||||||
|
|
||||||
const struct glsl_type *new_type = glsl_type_to_16bit(var->type);
|
const struct glsl_type *new_type = glsl_type_to_16bit(var->type);
|
||||||
if (var->type == new_type)
|
if (var->type == new_type)
|
||||||
return false;
|
return false;
|
||||||
@@ -408,7 +411,7 @@ nir_lower_mediump_vars_impl(nir_function_impl *impl, nir_variable_mode modes,
|
|||||||
|
|
||||||
if (modes & nir_var_function_temp) {
|
if (modes & nir_var_function_temp) {
|
||||||
nir_foreach_function_temp_variable(var, impl) {
|
nir_foreach_function_temp_variable(var, impl) {
|
||||||
any_lowered = try_lower_mediump_var(var, modes) || any_lowered;
|
any_lowered = try_lower_mediump_var(var, modes, NULL) || any_lowered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!any_lowered)
|
if (!any_lowered)
|
||||||
@@ -550,9 +553,50 @@ nir_lower_mediump_vars(nir_shader *shader, nir_variable_mode modes)
|
|||||||
bool progress = false;
|
bool progress = false;
|
||||||
|
|
||||||
if (modes & ~nir_var_function_temp) {
|
if (modes & ~nir_var_function_temp) {
|
||||||
nir_foreach_variable_in_shader(var, shader) {
|
/* Don't lower GLES mediump atomic ops to 16-bit -- no hardware is expecting that. */
|
||||||
progress = try_lower_mediump_var(var, modes) || progress;
|
struct set *no_lower_set = _mesa_pointer_set_create(NULL);
|
||||||
|
nir_foreach_block(block, nir_shader_get_entrypoint(shader)) {
|
||||||
|
nir_foreach_instr(instr, block) {
|
||||||
|
if (instr->type != nir_instr_type_intrinsic)
|
||||||
|
continue;
|
||||||
|
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||||
|
switch (intr->intrinsic) {
|
||||||
|
case nir_intrinsic_deref_atomic_add:
|
||||||
|
case nir_intrinsic_deref_atomic_imin:
|
||||||
|
case nir_intrinsic_deref_atomic_umin:
|
||||||
|
case nir_intrinsic_deref_atomic_imax:
|
||||||
|
case nir_intrinsic_deref_atomic_umax:
|
||||||
|
case nir_intrinsic_deref_atomic_and:
|
||||||
|
case nir_intrinsic_deref_atomic_or:
|
||||||
|
case nir_intrinsic_deref_atomic_xor:
|
||||||
|
case nir_intrinsic_deref_atomic_exchange:
|
||||||
|
case nir_intrinsic_deref_atomic_fadd:
|
||||||
|
case nir_intrinsic_deref_atomic_fmin:
|
||||||
|
case nir_intrinsic_deref_atomic_fmax:
|
||||||
|
case nir_intrinsic_deref_atomic_comp_swap:
|
||||||
|
case nir_intrinsic_deref_atomic_fcomp_swap: {
|
||||||
|
nir_deref_instr *deref = nir_src_as_deref(intr->src[0]);
|
||||||
|
nir_variable *var = nir_deref_instr_get_variable(deref);
|
||||||
|
|
||||||
|
/* If we have atomic derefs that we can't track, then don't lower any mediump. */
|
||||||
|
if (!var)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_mesa_set_add(no_lower_set, var);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nir_foreach_variable_in_shader(var, shader) {
|
||||||
|
progress = try_lower_mediump_var(var, modes, no_lower_set) || progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
ralloc_free(no_lower_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
nir_foreach_function(function, shader) {
|
nir_foreach_function(function, shader) {
|
||||||
|
|||||||
Reference in New Issue
Block a user