r300: skip draws instead of using a dummy vertex shader
authorPavel Ondračka <pavel.ondracka@gmail.com>
Sun, 8 May 2022 16:04:37 +0000 (18:04 +0200)
committerMarge Bot <emma+marge@anholt.net>
Mon, 9 May 2022 23:02:57 +0000 (23:02 +0000)
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@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
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_vs.c

index 9979538..ea36d0e 100644 (file)
@@ -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);
index 2e45fb0..a786d56 100644 (file)
@@ -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);
         }
     }
 }
index 6e9c4cd..776d838 100644 (file)
@@ -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;
     }