From 4a0cb910e44026ea0b7e7db41eea20247c277ca3 Mon Sep 17 00:00:00 2001 From: Sviatoslav Peleshko Date: Fri, 7 Nov 2025 02:13:59 +0200 Subject: [PATCH] mesa,driconf: Add WA to initialize vertex program outputs to vec4(0,0,0,1) Per ARB_vertex_program spec result registers are 4-component and initially undefined, and the FF fragment program expects its intputs to be 4-component too. So, if the client's vertex program does not write the whole vector it will cause misrenderings unless the same client also supplies fragment program that expects less than 4 componens. This commit adds a workaround that initializes results to vec4(0, 0, 0, 1) which seems to be an expected behavior for such clients. Cc: mesa-stable Signed-off-by: Sviatoslav Peleshko Reviewed-by: Timothy Arceri (cherry picked from commit f03432c81a268ad2cf683f176cf0b97c24a617b2) Part-of: --- .pick_status.json | 2 +- src/gallium/auxiliary/pipe-loader/driinfo_gallium.h | 1 + src/gallium/auxiliary/util/u_driconf.c | 1 + src/gallium/include/frontend/api.h | 1 + src/mesa/main/consts_exts.h | 3 +++ src/mesa/program/prog_to_nir.c | 7 +++++++ src/mesa/state_tracker/st_extensions.c | 2 ++ src/util/driconf.h | 4 ++++ 8 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.pick_status.json b/.pick_status.json index dcd5e1631cb..e758ad948c3 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -994,7 +994,7 @@ "description": "mesa,driconf: Add WA to initialize vertex program outputs to vec4(0,0,0,1)", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h index c9b04e14886..d39cd85ce18 100644 --- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h +++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h @@ -64,6 +64,7 @@ DRI_CONF_SECTION_END DRI_CONF_SECTION_MISCELLANEOUS DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER(false) DRI_CONF_GLSL_ZERO_INIT(false) + DRI_CONF_VERTEX_PROGRAM_DEFAULT_OUT(false) DRI_CONF_VS_POSITION_ALWAYS_INVARIANT(false) DRI_CONF_VS_POSITION_ALWAYS_PRECISE(false) DRI_CONF_ALLOW_RGB10_CONFIGS(true) diff --git a/src/gallium/auxiliary/util/u_driconf.c b/src/gallium/auxiliary/util/u_driconf.c index 6f62bf9240e..e37de3a7f70 100644 --- a/src/gallium/auxiliary/util/u_driconf.c +++ b/src/gallium/auxiliary/util/u_driconf.c @@ -76,6 +76,7 @@ u_driconf_fill_st_options(struct st_config_options *options, query_string_option(force_gl_renderer); query_string_option(mesa_extension_override); query_bool_option(allow_multisampled_copyteximage); + query_bool_option(vertex_program_default_out); driComputeOptionsSha1(optionCache, options->config_options_sha1); } diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h index d1af611e53d..f2c0da31eb3 100644 --- a/src/gallium/include/frontend/api.h +++ b/src/gallium/include/frontend/api.h @@ -205,6 +205,7 @@ struct st_config_options char *force_gl_renderer; char *mesa_extension_override; bool allow_multisampled_copyteximage; + bool vertex_program_default_out; unsigned char config_options_sha1[20]; }; diff --git a/src/mesa/main/consts_exts.h b/src/mesa/main/consts_exts.h index 57aaed546e3..1563b72b458 100644 --- a/src/mesa/main/consts_exts.h +++ b/src/mesa/main/consts_exts.h @@ -944,6 +944,9 @@ struct gl_constants */ bool GLThreadNopCheckFramebufferStatus; + /** (driconf) Initialize outputs of vertex program to a default value vec4(0, 0, 0, 1) */ + GLboolean VertexProgramDefaultOut; + /** GL_ARB_sparse_texture */ GLuint MaxSparseTextureSize; GLuint MaxSparse3DTextureSize; diff --git a/src/mesa/program/prog_to_nir.c b/src/mesa/program/prog_to_nir.c index 3e12b947d00..3b3b6cac90b 100644 --- a/src/mesa/program/prog_to_nir.c +++ b/src/mesa/program/prog_to_nir.c @@ -784,6 +784,13 @@ setup_registers_and_variables(struct ptn_compile *c) * the shader. */ c->output_regs[i] = nir_decl_reg(b, 4, 32, 0); + + /* Initialize output registers with default value vec4(0, 0, 0, 1) */ + if (c->ctx->Const.VertexProgramDefaultOut && + c->prog->info.stage == MESA_SHADER_VERTEX && + i != VARYING_SLOT_FOGC && i <= VARYING_SLOT_TEX7) { + nir_store_reg(b, nir_imm_vec4(b, 0, 0, 0, 1), c->output_regs[i]); + } } /* Create temporary registers. */ diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index bbd3fd06a94..f5f360eb80c 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -1331,6 +1331,8 @@ void st_init_extensions(struct pipe_screen *screen, consts->GLSLZeroInit = screen->caps.glsl_zero_init; } + consts->VertexProgramDefaultOut = options->vertex_program_default_out; + if (extensions->EXT_semaphore) { consts->MaxTimelineSemaphoreValueDifference = screen->caps.max_timeline_semaphore_difference; extensions->NV_timeline_semaphore = consts->MaxTimelineSemaphoreValueDifference > 0; diff --git a/src/util/driconf.h b/src/util/driconf.h index d6338e80305..6f478b04ff6 100644 --- a/src/util/driconf.h +++ b/src/util/driconf.h @@ -520,6 +520,10 @@ DRI_CONF_OPT_B(allow_multisampled_copyteximage, def, \ "Allow CopyTexSubImage and other to copy sampled framebuffer") +#define DRI_CONF_VERTEX_PROGRAM_DEFAULT_OUT(def) \ + DRI_CONF_OPT_B(vertex_program_default_out, def, \ + "Initialize outputs of vertex program to a default value vec4(0, 0, 0, 1)") + #define DRI_CONF_CUSTOM_BORDER_COLORS_WITHOUT_FORMAT(def) \ DRI_CONF_OPT_B(custom_border_colors_without_format, def, \ "Enable custom border colors without format")