From c6aa639ba9b283c7b2735ed3d682403d585a15d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Ondra=C4=8Dka?= Date: Sun, 8 May 2022 18:04:37 +0200 Subject: [PATCH] r300: skip draws instead of using a dummy vertex shader MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5870 Part-of: --- 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 @@ -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; }