From 9fe8ae3fcde8d7608d5b03ace51a4a3cebf18fee Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 30 Jul 2021 11:48:28 +0200 Subject: [PATCH] radeonsi: don't create an infinite number of variants MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit If a shader has code like this: uniform float timestamp; ... if (timestamp > 0.0) do_something() And timestamp is modified each frame, we'll end up generating a new variant per frame. This commit introduces a hard limit on the number of variants we generate for a single shader. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5121 Fixes: b7501184b90 ("radeonsi: implement inlinable uniforms") Reviewed-by: Marek Olšák Part-of: --- src/gallium/drivers/radeonsi/si_shader.h | 3 +++ src/gallium/drivers/radeonsi/si_state_shaders.c | 25 +++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index b3847db..9cdf8ad 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -698,6 +698,9 @@ struct si_shader_key { unsigned inline_uniforms:1; + /* This must be kept last to limit the number of variants + * depending only on the uniform values. + */ uint32_t inlined_uniform_values[MAX_INLINABLE_UNIFORMS]; } opt; }; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 51db88a..cb28301 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -2243,10 +2243,31 @@ current_not_ready: simple_mtx_lock(&sel->mutex); + /* Compute the size of the key without the uniform values. */ + size_t s = (void*)&key->opt.inlined_uniform_values - (void*)key; + int variant_count = 0; + const int max_inline_uniforms_variants = 5; + /* Find the shader variant. */ for (iter = sel->first_variant; iter; iter = iter->next_variant) { - /* Don't check the "current" shader. We checked it above. */ - if (current != iter && memcmp(&iter->key, key, sizeof(*key)) == 0) { + if (memcmp(&iter->key, key, s) == 0) { + /* Check the inlined uniform values separatly, and count + * the number of variants based on them. + */ + if (key->opt.inline_uniforms && + memcmp(iter->key.opt.inlined_uniform_values, + key->opt.inlined_uniform_values, + MAX_INLINABLE_UNIFORMS * 4) != 0) { + if (variant_count++ > max_inline_uniforms_variants) { + /* Too many variants. Disable inlining for this shader. */ + key->opt.inline_uniforms = 0; + memset(key->opt.inlined_uniform_values, 0, MAX_INLINABLE_UNIFORMS * 4); + simple_mtx_unlock(&sel->mutex); + goto again; + } + continue; + } + simple_mtx_unlock(&sel->mutex); if (unlikely(!util_queue_fence_is_signalled(&iter->ready))) { -- 2.7.4