Mesa (main): r300: skip draws instead of using a dummy vertex shader

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon May 9 23:09:54 UTC 2022


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

Author: Pavel Ondračka <pavel.ondracka at gmail.com>
Date:   Sun May  8 18:04:37 2022 +0200

r300: skip draws instead of using a dummy vertex shader

When we fail to compile some vertex shader, we currently use a very
simple dummy one, setting gl_Position to (0,0,0,1), effectively
rendering nothing. Unfortunately, the dummy vertex shader leads to
hangs with RV370 in some rare circumstances. Instead of trying to
fix the shader, just skip the draws altogether when the compilation
fails.

Signed-off-by: Pavel Ondračka <pavel.ondracka at gmail.com>
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5870
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16387>

---

 src/gallium/drivers/r300/r300_render.c        |  5 ++++
 src/gallium/drivers/r300/r300_state_derived.c |  6 ++--
 src/gallium/drivers/r300/r300_vs.c            | 43 ++++-----------------------
 3 files changed, 15 insertions(+), 39 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 9979538d07d..ea36d0e1671 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -40,6 +40,7 @@
 #include "r300_screen_buffer.h"
 #include "r300_emit.h"
 #include "r300_reg.h"
+#include "r300_vs.h"
 
 #include <limits.h>
 
@@ -815,6 +816,10 @@ static void r300_draw_vbo(struct pipe_context* pipe,
 
     r300_update_derived_state(r300);
 
+    /* Skip draw if we failed to compile the vertex shader. */
+    if (r300_vs(r300)->shader->dummy)
+        return;
+
     /* Draw. */
     if (info.index_size) {
         unsigned max_count = r300_max_vertex_count(r300);
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 2e45fb0c7d2..a786d56d8b9 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -1074,7 +1074,8 @@ static void r300_pick_vertex_shader(struct r300_context *r300)
             vs->first = vs->shader = CALLOC_STRUCT(r300_vertex_shader_code);
             vs->first->wpos = wpos;
             r300_translate_vertex_shader(r300, vs);
-            r300_mark_atom_dirty(r300, &r300->rs_block_state);
+            if (!vs->first->dummy)
+                r300_mark_atom_dirty(r300, &r300->rs_block_state);
             return;
         }
         /* Pick the vertex shader based on whether we need wpos */
@@ -1091,7 +1092,8 @@ static void r300_pick_vertex_shader(struct r300_context *r300)
                 vs->shader->wpos = wpos;
                 r300_translate_vertex_shader(r300, vs);
             }
-            r300_mark_atom_dirty(r300, &r300->rs_block_state);
+            if (!vs->first->dummy)
+                r300_mark_atom_dirty(r300, &r300->rs_block_state);
         }
     }
 }
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index 6e9c4cd65db..776d838f695 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -178,30 +178,6 @@ void r300_init_vs_outputs(struct r300_context *r300,
     r300_shader_read_vs_outputs(r300, &vs->shader->info, &vs->shader->outputs);
 }
 
-static void r300_dummy_vertex_shader(
-    struct r300_context* r300,
-    struct r300_vertex_shader* vs)
-{
-    struct ureg_program *ureg;
-    struct ureg_dst dst;
-    struct ureg_src imm;
-
-    /* Make a simple vertex shader which outputs (0, 0, 0, 1),
-     * effectively rendering nothing. */
-    ureg = ureg_create(PIPE_SHADER_VERTEX);
-    dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
-    imm = ureg_imm4f(ureg, 0, 0, 0, 1);
-
-    ureg_MOV(ureg, dst, imm);
-    ureg_END(ureg);
-
-    vs->state.tokens = tgsi_dup_tokens(ureg_finalize(ureg));
-    ureg_destroy(ureg);
-
-    vs->shader->dummy = TRUE;
-    r300_translate_vertex_shader(r300, vs);
-}
-
 void r300_translate_vertex_shader(struct r300_context *r300,
                                   struct r300_vertex_shader *shader)
 {
@@ -219,8 +195,7 @@ void r300_translate_vertex_shader(struct r300_context *r300,
     DBG_ON(r300, DBG_VP) ? compiler.Base.Debug |= RC_DBG_LOG : 0;
     compiler.code = &vs->code;
     compiler.UserData = vs;
-    if (!vs->dummy)
-        compiler.Base.debug = &r300->debug;
+    compiler.Base.debug = &r300->debug;
     compiler.Base.is_r500 = r300->screen->caps.is_r500;
     compiler.Base.disable_optimizations = DBG_ON(r300, DBG_NO_OPT);
     compiler.Base.has_half_swizzles = FALSE;
@@ -245,8 +220,8 @@ void r300_translate_vertex_shader(struct r300_context *r300,
 
     if (ttr.error) {
         fprintf(stderr, "r300 VP: Cannot translate a shader. "
-                "Using a dummy shader instead.\n");
-        r300_dummy_vertex_shader(r300, shader);
+                "Corresponding draws will be skipped.\n");
+        vs->dummy = TRUE;
         return;
     }
 
@@ -264,17 +239,11 @@ void r300_translate_vertex_shader(struct r300_context *r300,
     /* Invoke the compiler */
     r3xx_compile_vertex_program(&compiler);
     if (compiler.Base.Error) {
-        fprintf(stderr, "r300 VP: Compiler error:\n%sUsing a dummy shader"
-                " instead.\n", compiler.Base.ErrorMsg);
-
-        if (vs->dummy) {
-            fprintf(stderr, "r300 VP: Cannot compile the dummy shader! "
-                    "Giving up...\n");
-            abort();
-        }
+        fprintf(stderr, "r300 VP: Compiler error:\n%sCorresponding draws will be"
+                " skipped.\n", compiler.Base.ErrorMsg);
 
         rc_destroy(&compiler.Base);
-        r300_dummy_vertex_shader(r300, shader);
+        vs->dummy = TRUE;
         return;
     }
 



More information about the mesa-commit mailing list