Mesa (main): radv: re-emit prolog inputs when the nontrivial divisors state changed

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Oct 22 09:36:01 UTC 2021


Module: Mesa
Branch: main
Commit: b6a69dbb40d06963056b14158acd0521a91fc395
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b6a69dbb40d06963056b14158acd0521a91fc395

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Fri Oct 15 14:27:38 2021 +0200

radv: re-emit prolog inputs when the nontrivial divisors state changed

If the application first uses nontrivial divisors, the driver emits
the vertex shader VA to the upload BO rather than directly via the
user SGPRs locations. But, if the vertex input dynamic state changes,
the driver might select a different VS prolog that no longer needs
nontrivial divisors.

In this case, the driver needs to re-emit the prolog inputs because
otherwise the VS prolog will jump to the PC that is emitted via the
user SGPR locations, and the previous one was somewhere in the
upload BO...

This fixes a GPU hang with Bioshock and Zink.

Fixes: d9c7a175424 ("radv: enable VK_EXT_vertex_input_dynamic_state")
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Rhys Perry <pendingchaos02 at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13377>

---

 src/amd/vulkan/radv_cmd_buffer.c | 3 ++-
 src/amd/vulkan/radv_shader.c     | 3 +++
 src/amd/vulkan/radv_shader.h     | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 3c7882a8297..43cdf378531 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -2911,7 +2911,8 @@ emit_prolog_inputs(struct radv_cmd_buffer *cmd_buffer, struct radv_shader_varian
                    uint32_t nontrivial_divisors, bool pipeline_is_dirty)
 {
    /* no need to re-emit anything in this case */
-   if (!nontrivial_divisors && !pipeline_is_dirty)
+   if (!nontrivial_divisors && !pipeline_is_dirty && cmd_buffer->state.emitted_vs_prolog &&
+       !cmd_buffer->state.emitted_vs_prolog->nontrivial_divisors)
       return;
 
    struct radv_vs_input_state *state = &cmd_buffer->state.dynamic_vs_input;
diff --git a/src/amd/vulkan/radv_shader.c b/src/amd/vulkan/radv_shader.c
index 41554fa055d..96524475164 100644
--- a/src/amd/vulkan/radv_shader.c
+++ b/src/amd/vulkan/radv_shader.c
@@ -1971,6 +1971,9 @@ radv_create_vs_prolog(struct radv_device *device, const struct radv_vs_prolog_ke
    struct radv_prolog_binary *binary = NULL;
    aco_compile_vs_prolog(&options, &info, key, &args, &binary);
    struct radv_shader_prolog *prolog = upload_vs_prolog(device, binary, info.wave_size);
+   if (prolog) {
+      prolog->nontrivial_divisors = key->state->nontrivial_divisors;
+   }
    free(binary);
 
    return prolog;
diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h
index 4204e5a5b30..9cabbfc21c1 100644
--- a/src/amd/vulkan/radv_shader.h
+++ b/src/amd/vulkan/radv_shader.h
@@ -479,6 +479,7 @@ struct radv_shader_prolog {
    union radv_shader_arena_block *alloc;
    uint32_t rsrc1;
    uint8_t num_preserved_sgprs;
+   bool nontrivial_divisors;
 };
 
 void radv_optimize_nir(const struct radv_device *device, struct nir_shader *shader,



More information about the mesa-commit mailing list