anv: fix streamout config comparison
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: e76ed91d3f ("anv: switch over to runtime pipelines")
Acked-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37251>
This commit is contained in:
Lionel Landwerlin 2025-09-09 14:22:56 +03:00 committed by Marge Bot
parent 8e93e7cd72
commit 1d8847afcf
2 changed files with 49 additions and 45 deletions

View file

@ -668,7 +668,6 @@ wayland-dEQP-EGL.functional.resize.surface_size.stretch_width,Fail
# shader objects #13839 # shader objects #13839
KHR-GL46.separable_programs_tf.tessellation_active,Fail
spec@arb_fragment_program@fog-modes,Crash spec@arb_fragment_program@fog-modes,Crash
spec@arb_occlusion_query@occlusion_query_meta_fragments,Fail spec@arb_occlusion_query@occlusion_query_meta_fragments,Fail
spec@arb_occlusion_query@occlusion_query_meta_save,Fail spec@arb_occlusion_query@occlusion_query_meta_save,Fail

View file

@ -53,6 +53,7 @@ anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
state->gfx.restart_index = UINT32_MAX; state->gfx.restart_index = UINT32_MAX;
state->gfx.object_preemption = true; state->gfx.object_preemption = true;
state->gfx.dirty = 0; state->gfx.dirty = 0;
state->gfx.streamout_stage = MESA_SHADER_NONE;
state->compute.pixel_async_compute_thread_limit = UINT8_MAX; state->compute.pixel_async_compute_thread_limit = UINT8_MAX;
state->compute.z_pass_async_compute_thread_limit = UINT8_MAX; state->compute.z_pass_async_compute_thread_limit = UINT8_MAX;
@ -1480,7 +1481,7 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer,
gfx->active_stages = 0; gfx->active_stages = 0;
gfx->instance_multiplier = 0; gfx->instance_multiplier = 0;
mesa_shader_stage new_streamout_stage = -1; mesa_shader_stage new_streamout_stage = MESA_SHADER_NONE;
/* Find the last pre-rasterization stage */ /* Find the last pre-rasterization stage */
for (uint32_t i = 0; i < ANV_GRAPHICS_SHADER_STAGE_COUNT; i++) { for (uint32_t i = 0; i < ANV_GRAPHICS_SHADER_STAGE_COUNT; i++) {
mesa_shader_stage s = ANV_GRAPHICS_SHADER_STAGE_COUNT - i - 1; mesa_shader_stage s = ANV_GRAPHICS_SHADER_STAGE_COUNT - i - 1;
@ -1500,6 +1501,53 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer,
new_streamout_stage = MAX2(new_streamout_stage, s); new_streamout_stage = MAX2(new_streamout_stage, s);
} }
#define diff_fix_state_stage(bit, name, old_stage, shader) \
do { \
/* Fixed states should always have matching sizes */ \
assert(old_stage == MESA_SHADER_NONE || \
gfx->shaders[old_stage] == NULL || \
gfx->shaders[old_stage]->name.len == shader->name.len); \
/* Don't bother memcmp if the state is already dirty */ \
if (!BITSET_TEST(hw_state->pack_dirty, ANV_GFX_STATE_##bit) && \
(old_stage == MESA_SHADER_NONE || \
gfx->shaders[old_stage] == NULL || \
memcmp(&gfx->shaders[old_stage]->cmd_data[ \
gfx->shaders[old_stage]->name.offset], \
&shader->cmd_data[ \
shader->name.offset], \
4 * shader->name.len) != 0)) \
BITSET_SET(hw_state->pack_dirty, ANV_GFX_STATE_##bit); \
} while (0)
#define diff_var_state_stage(bit, name, old_stage,shader) \
do { \
/* Don't bother memcmp if the state is already dirty */ \
/* Also if the new state is empty, avoid marking dirty */ \
if (!BITSET_TEST(hw_state->pack_dirty, ANV_GFX_STATE_##bit) && \
shader->name.len != 0 && \
(gfx->shaders[old_stage] == NULL || \
gfx->shaders[old_stage]->name.len != shader->name.len || \
memcmp(&gfx->shaders[old_stage]->cmd_data[ \
gfx->shaders[old_stage]->name.offset], \
&shader->cmd_data[shader->name.offset], \
4 * shader->name.len) != 0)) \
BITSET_SET(hw_state->pack_dirty, ANV_GFX_STATE_##bit); \
} while (0)
if (new_streamout_stage != MESA_SHADER_NONE) {
/* Compare the stream instructions first because we go through the
* stages of shaders and update gfx->shaders[], we can't compare the old
* streamout configuration from the old vertex shader with the new
* configuration of the tessellation shader.
*/
diff_fix_state_stage(STREAMOUT, so, gfx->streamout_stage, new_shaders[new_streamout_stage]);
diff_var_state_stage(SO_DECL_LIST, so_decl_list, gfx->streamout_stage, new_shaders[new_streamout_stage]);
gfx->streamout_stage = new_streamout_stage;
}
#undef diff_fix_state_stage
#undef diff_var_state_stage
for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) { for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
struct anv_shader *shader = new_shaders[s]; struct anv_shader *shader = new_shaders[s];
@ -1547,39 +1595,6 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer,
4 * shader->name.len) != 0)) \ 4 * shader->name.len) != 0)) \
BITSET_SET(hw_state->pack_dirty, ANV_GFX_STATE_##bit); \ BITSET_SET(hw_state->pack_dirty, ANV_GFX_STATE_##bit); \
} while (0) } while (0)
#define diff_fix_state_stage(bit, name, old_stage) \
do { \
/* Fixed states should always have matching sizes */ \
assert(old_stage == MESA_SHADER_NONE || \
gfx->shaders[old_stage] == NULL || \
gfx->shaders[old_stage]->name.len == shader->name.len); \
/* Don't bother memcmp if the state is already dirty */ \
if (!BITSET_TEST(hw_state->pack_dirty, \
ANV_GFX_STATE_##bit) && \
(old_stage == MESA_SHADER_NONE || \
gfx->shaders[old_stage] == NULL || \
memcmp(&gfx->shaders[old_stage]->cmd_data[ \
gfx->shaders[old_stage]->name.offset], \
&shader->cmd_data[ \
shader->name.offset], \
4 * shader->name.len) != 0)) \
BITSET_SET(hw_state->pack_dirty, ANV_GFX_STATE_##bit); \
} while (0)
#define diff_var_state_stage(bit, name, old_stage) \
do { \
/* Don't bother memcmp if the state is already dirty */ \
/* Also if the new state is empty, avoid marking dirty */ \
if (!BITSET_TEST(hw_state->pack_dirty, \
ANV_GFX_STATE_##bit) && \
shader->name.len != 0 && \
(gfx->shaders[old_stage] == NULL || \
gfx->shaders[old_stage]->name.len != shader->name.len || \
memcmp(&gfx->shaders[old_stage]->cmd_data[ \
gfx->shaders[old_stage]->name.offset], \
&shader->cmd_data[shader->name.offset], \
4 * shader->name.len) != 0)) \
BITSET_SET(hw_state->pack_dirty, ANV_GFX_STATE_##bit); \
} while (0)
switch (s) { switch (s) {
case MESA_SHADER_VERTEX: case MESA_SHADER_VERTEX:
@ -1656,21 +1671,11 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer,
UNREACHABLE("Invalid shader stage"); UNREACHABLE("Invalid shader stage");
} }
/* Only diff those field on the streamout stage */
if (s == new_streamout_stage) {
diff_fix_state_stage(STREAMOUT, so, gfx->streamout_stage);
diff_var_state_stage(SO_DECL_LIST, so_decl_list, gfx->streamout_stage);
}
gfx->shaders[s] = shader; gfx->shaders[s] = shader;
} }
gfx->streamout_stage = new_streamout_stage;
#undef diff_fix_state #undef diff_fix_state
#undef diff_var_state #undef diff_var_state
#undef diff_fix_state_stage
#undef diff_var_state_stage
update_push_descriptor_flags(&gfx->base, update_push_descriptor_flags(&gfx->base,
cmd_buffer->state.gfx.shaders, cmd_buffer->state.gfx.shaders,