From 9c5e15e6f5b49a9882fe82d2aa9909ee20d84bdd Mon Sep 17 00:00:00 2001 From: Patrick Lerda Date: Mon, 12 Jan 2026 15:49:12 +0100 Subject: [PATCH] r600: improve vs_as_ls switch reliability This change updates the vs_as_ls switch logic to make it reliable. It resets the dirty flag when the switch is happening. It uses also evergreen_emit_vs_constant_buffers() to try to update again some of the states which could be lost otherwise. This change fixes some "flakes". These tests needed previously to be executed twice to set the hardware in the proper state for the test to pass. It also fixes the main issue of the texture_view.view_sampling test. This change was tested on palm and cayman. Here are the tests which are now utterly fixed: khr-gl4[3-6]/stencil_texturing/functional: fail pass khr-gl4[4-6]/texture_cube_map_array/texture_size_tesselation_ev_sh: fail pass khr-gles31/core/texture_cube_map_array/texture_size_tesselation_ev_sh: fail pass khr-glesext/texture_cube_map_array/texture_size_tesselation_ev_sh: fail pass Fixes: 25f96c1120f0 ("r600: hook up constants/samplers/sampler view for tessellation") Signed-off-by: Patrick Lerda Acked-by: Gert Wollny Part-of: --- .../drivers/r600/ci/r600-turks-fails.txt | 1 - .../drivers/r600/ci/r600-turks-flakes.txt | 7 -- src/gallium/drivers/r600/evergreen_state.c | 84 +++++++++++++++++-- src/gallium/drivers/r600/r600_pipe.h | 3 + src/gallium/drivers/r600/r600_shader_common.h | 2 +- 5 files changed, 80 insertions(+), 17 deletions(-) diff --git a/src/gallium/drivers/r600/ci/r600-turks-fails.txt b/src/gallium/drivers/r600/ci/r600-turks-fails.txt index eb3045e1c42..adf9f530ef5 100644 --- a/src/gallium/drivers/r600/ci/r600-turks-fails.txt +++ b/src/gallium/drivers/r600/ci/r600-turks-fails.txt @@ -42,7 +42,6 @@ KHR-GLES31.core.texture_buffer.texture_buffer_max_size,Fail KHR-GLES31.core.texture_buffer.texture_buffer_texture_buffer_range,Fail KHR-GLES31.core.texture_cube_map_array.sampling,Fail -KHR-GLES31.core.texture_cube_map_array.texture_size_tesselation_ev_sh,Fail KHR-GLES31.core.vertex_attrib_binding.basic-input-case5,Fail KHR-GLES31.core.vertex_attrib_binding.basic-input-case6,Fail diff --git a/src/gallium/drivers/r600/ci/r600-turks-flakes.txt b/src/gallium/drivers/r600/ci/r600-turks-flakes.txt index 4b8489e94d0..2438cfc20fc 100644 --- a/src/gallium/drivers/r600/ci/r600-turks-flakes.txt +++ b/src/gallium/drivers/r600/ci/r600-turks-flakes.txt @@ -18,10 +18,3 @@ spec@arb_shader_image_load_store@invalid@ # Unclear if just parallel issues, but GPU timestamps seem to run a bit fast. spec@arb_timer_query@timestamp-get spec@ext_timer_query@time-elapsed - -spec@arb_texture_cube_map_array@texturesize@tes-texturesize-samplercubearrayshadow -spec@glsl-1.50@execution@texturesize@tes-texturesize-sampler1darrayshadow -spec@glsl-1.50@execution@texturesize@tes-texturesize-sampler1dshadow -spec@glsl-1.50@execution@texturesize@tes-texturesize-sampler2darrayshadow -spec@glsl-1.50@execution@texturesize@tes-texturesize-sampler2dshadow -spec@glsl-1.50@execution@texturesize@tes-texturesize-samplercubeshadow diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 75f7357b10a..a1255258ece 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -22,6 +22,13 @@ #include +static inline void evergreen_switch_samplerview_shared_state(struct r600_samplerview_state *const view, + const bool shared_state); +static inline void evergreen_to_ls_mode(struct r600_context *const rctx, + struct r600_constbuf_state *const state); +static inline void evergreen_to_vs_mode(struct r600_context *const rctx, + struct r600_constbuf_state *const state); + static const unsigned neutral_swz[4] = { PIPE_SWIZZLE_X, PIPE_SWIZZLE_Y, PIPE_SWIZZLE_Z, PIPE_SWIZZLE_W }; @@ -2367,14 +2374,19 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx, /* VS constants can be in VS/ES (same space) or LS if tess is enabled */ static void evergreen_emit_vs_constant_buffers(struct r600_context *rctx, struct r600_atom *atom) { + struct r600_constbuf_state *const state = &rctx->constbuf_state[MESA_SHADER_VERTEX]; if (rctx->vs_shader->current->shader.vs_as_ls) { - evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[MESA_SHADER_VERTEX], + if (unlikely(!state->shared_state)) + evergreen_to_ls_mode(rctx, state); + evergreen_emit_constant_buffers(rctx, state, EG_FETCH_CONSTANTS_OFFSET_LS, R_028FC0_ALU_CONST_BUFFER_SIZE_LS_0, R_028F40_ALU_CONST_CACHE_LS_0, 0 /* PKT3 flags */); } else { - evergreen_emit_constant_buffers(rctx, &rctx->constbuf_state[MESA_SHADER_VERTEX], + if (unlikely(state->shared_state)) + evergreen_to_vs_mode(rctx, state); + evergreen_emit_constant_buffers(rctx, state, EG_FETCH_CONSTANTS_OFFSET_VS, R_028180_ALU_CONST_BUFFER_SIZE_VS_0, R_028980_ALU_CONST_CACHE_VS_0, @@ -2491,11 +2503,14 @@ static void evergreen_emit_sampler_views(struct r600_context *rctx, static void evergreen_emit_vs_sampler_views(struct r600_context *rctx, struct r600_atom *atom) { - if (rctx->vs_shader->current->shader.vs_as_ls) { - evergreen_emit_sampler_views(rctx, &rctx->samplers[MESA_SHADER_VERTEX].views, + struct r600_samplerview_state *const state_vs_view = &rctx->samplers[MESA_SHADER_VERTEX].views; + const bool vs_as_ls = rctx->vs_shader->current->shader.vs_as_ls; + evergreen_switch_samplerview_shared_state(state_vs_view, vs_as_ls); + if (vs_as_ls) { + evergreen_emit_sampler_views(rctx, state_vs_view, EG_FETCH_CONSTANTS_OFFSET_LS + R600_MAX_CONST_BUFFERS, 0); } else { - evergreen_emit_sampler_views(rctx, &rctx->samplers[MESA_SHADER_VERTEX].views, + evergreen_emit_sampler_views(rctx, state_vs_view, EG_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS, 0); } } @@ -2858,13 +2873,25 @@ static void evergreen_emit_sampler_states(struct r600_context *rctx, texinfo->states.dirty_mask = 0; } +static inline void evergreen_switch_sampler_shared_state(struct r600_textures_info *const sampler, + const bool shared_state) +{ + if (unlikely(shared_state != sampler->states.shared_state)) { + sampler->states.dirty_mask = sampler->states.enabled_mask; + sampler->states.shared_state = shared_state; + } +} + static void evergreen_emit_vs_sampler_states(struct r600_context *rctx, struct r600_atom *atom) { - if (rctx->vs_shader->current->shader.vs_as_ls) { - evergreen_emit_sampler_states(rctx, &rctx->samplers[MESA_SHADER_VERTEX], 72, + struct r600_textures_info *const vs_sampler = &rctx->samplers[MESA_SHADER_VERTEX]; + const bool vs_as_ls = rctx->vs_shader->current->shader.vs_as_ls; + evergreen_switch_sampler_shared_state(vs_sampler, vs_as_ls); + if (vs_as_ls) { + evergreen_emit_sampler_states(rctx, vs_sampler, 72, R_00A450_TD_LS_SAMPLER0_BORDER_COLOR_INDEX, 0); } else { - evergreen_emit_sampler_states(rctx, &rctx->samplers[MESA_SHADER_VERTEX], 18, + evergreen_emit_sampler_states(rctx, vs_sampler, 18, R_00A414_TD_VS_SAMPLER0_BORDER_INDEX, 0); } } @@ -5496,3 +5523,44 @@ void evergreen_emit_atomic_buffer_save(struct r600_context *rctx, radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); radeon_emit(cs, reloc); } + +static inline void evergreen_switch_samplerview_shared_state(struct r600_samplerview_state *const view, + const bool shared_state) +{ + if (unlikely(shared_state != view->shared_state)) { + view->dirty_mask = view->enabled_mask; + view->shared_state = shared_state; + } +} + +static inline void evergreen_to_ls_mode(struct r600_context *const rctx, + struct r600_constbuf_state *const state) +{ + assert(!state->shared_state); + + state->dirty_mask = state->enabled_mask; + state->shared_state = true; + + struct r600_samplerview_state *const state_tes_view = &rctx->samplers[MESA_SHADER_TESS_EVAL].views; + evergreen_emit_sampler_views(rctx, state_tes_view, + EG_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS, 0); + + struct r600_samplerview_state *const state_vs_view = &rctx->samplers[MESA_SHADER_VERTEX].views; + evergreen_switch_samplerview_shared_state(state_vs_view, true); + evergreen_emit_sampler_views(rctx, state_vs_view, + EG_FETCH_CONSTANTS_OFFSET_LS + R600_MAX_CONST_BUFFERS, 0); +} + +static inline void evergreen_to_vs_mode(struct r600_context *const rctx, + struct r600_constbuf_state *const state) +{ + assert(state->shared_state); + + state->dirty_mask = state->enabled_mask; + state->shared_state = false; + + struct r600_samplerview_state *const state_vs_view = &rctx->samplers[MESA_SHADER_VERTEX].views; + evergreen_switch_samplerview_shared_state(state_vs_view, false); + evergreen_emit_sampler_views(rctx, state_vs_view, + EG_FETCH_CONSTANTS_OFFSET_VS + R600_MAX_CONST_BUFFERS, 0); +} diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 8cf9f4c34cd..c4e81ba3988 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -364,6 +364,7 @@ struct r600_samplerview_state { uint32_t compressed_depthtex_mask; /* which textures are depth */ uint32_t compressed_colortex_mask; bool dirty_buffer_constants; + bool shared_state; }; struct r600_sampler_states { @@ -372,6 +373,7 @@ struct r600_sampler_states { uint32_t enabled_mask; uint32_t dirty_mask; uint32_t has_bordercolor_mask; /* which states contain the border color */ + bool shared_state; }; struct r600_textures_info { @@ -397,6 +399,7 @@ struct r600_constbuf_state struct pipe_constant_buffer cb[PIPE_MAX_CONSTANT_BUFFERS]; uint32_t enabled_mask; uint32_t dirty_mask; + bool shared_state; }; struct r600_vertexbuf_state diff --git a/src/gallium/drivers/r600/r600_shader_common.h b/src/gallium/drivers/r600/r600_shader_common.h index c4f2b427d14..0e2c642f3f8 100644 --- a/src/gallium/drivers/r600/r600_shader_common.h +++ b/src/gallium/drivers/r600/r600_shader_common.h @@ -99,7 +99,7 @@ struct r600_shader { unsigned max_arrays; unsigned num_arrays; unsigned vs_as_es; - unsigned vs_as_ls; + bool vs_as_ls; unsigned vs_as_gs_a; unsigned tes_as_es; unsigned tcs_prim_mode;