anv: add dirty tracking for push constant data

This allows us to skip allocating state if it exists already. There are
different scenarios where this can help: when updating only descriptors
(not push constant data) and after blorp or simple shader run.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10898
Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28689>
This commit is contained in:
Tapani Pälli 2024-04-10 09:52:55 +03:00
parent 899263ecfc
commit 62d96a6546
6 changed files with 32 additions and 6 deletions

View File

@ -497,6 +497,7 @@ anv_cmd_buffer_set_ray_query_buffer(struct anv_cmd_buffer *cmd_buffer,
pipeline_state->push_constants.ray_query_globals = pipeline_state->push_constants.ray_query_globals =
anv_address_physical(ray_query_globals_addr); anv_address_physical(ray_query_globals_addr);
cmd_buffer->state.push_constants_dirty |= stages; cmd_buffer->state.push_constants_dirty |= stages;
pipeline_state->push_constants_data_dirty = true;
} }
/** /**
@ -696,14 +697,17 @@ void anv_CmdBindPipeline(
modified = true; modified = true;
} }
} }
if (modified) if (modified) {
cmd_buffer->state.push_constants_dirty |= stages; cmd_buffer->state.push_constants_dirty |= stages;
state->push_constants_data_dirty = true;
}
} }
if ((new_pipeline->fs_msaa_flags & INTEL_MSAA_FLAG_ENABLE_DYNAMIC) && if ((new_pipeline->fs_msaa_flags & INTEL_MSAA_FLAG_ENABLE_DYNAMIC) &&
push->gfx.fs_msaa_flags != new_pipeline->fs_msaa_flags) { push->gfx.fs_msaa_flags != new_pipeline->fs_msaa_flags) {
push->gfx.fs_msaa_flags = new_pipeline->fs_msaa_flags; push->gfx.fs_msaa_flags = new_pipeline->fs_msaa_flags;
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
state->push_constants_data_dirty = true;
} }
anv_cmd_buffer_flush_pipeline_state(cmd_buffer, old_pipeline, new_pipeline); anv_cmd_buffer_flush_pipeline_state(cmd_buffer, old_pipeline, new_pipeline);
@ -922,6 +926,7 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
else else
cmd_buffer->state.descriptors_dirty |= dirty_stages; cmd_buffer->state.descriptors_dirty |= dirty_stages;
cmd_buffer->state.push_constants_dirty |= dirty_stages; cmd_buffer->state.push_constants_dirty |= dirty_stages;
pipe_state->push_constants_data_dirty = true;
} }
#define ANV_GRAPHICS_STAGE_BITS \ #define ANV_GRAPHICS_STAGE_BITS \
@ -1306,6 +1311,7 @@ void anv_CmdPushConstants2KHR(
memcpy(pipe_state->push_constants.client_data + pInfo->offset, memcpy(pipe_state->push_constants.client_data + pInfo->offset,
pInfo->pValues, pInfo->size); pInfo->pValues, pInfo->size);
pipe_state->push_constants_data_dirty = true;
} }
if (pInfo->stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) { if (pInfo->stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
struct anv_cmd_pipeline_state *pipe_state = struct anv_cmd_pipeline_state *pipe_state =
@ -1313,6 +1319,7 @@ void anv_CmdPushConstants2KHR(
memcpy(pipe_state->push_constants.client_data + pInfo->offset, memcpy(pipe_state->push_constants.client_data + pInfo->offset,
pInfo->pValues, pInfo->size); pInfo->pValues, pInfo->size);
pipe_state->push_constants_data_dirty = true;
} }
if (pInfo->stageFlags & ANV_RT_STAGE_BITS) { if (pInfo->stageFlags & ANV_RT_STAGE_BITS) {
struct anv_cmd_pipeline_state *pipe_state = struct anv_cmd_pipeline_state *pipe_state =
@ -1320,6 +1327,7 @@ void anv_CmdPushConstants2KHR(
memcpy(pipe_state->push_constants.client_data + pInfo->offset, memcpy(pipe_state->push_constants.client_data + pInfo->offset,
pInfo->pValues, pInfo->size); pInfo->pValues, pInfo->size);
pipe_state->push_constants_data_dirty = true;
} }
cmd_buffer->state.push_constants_dirty |= pInfo->stageFlags; cmd_buffer->state.push_constants_dirty |= pInfo->stageFlags;

View File

@ -3556,6 +3556,9 @@ struct anv_cmd_pipeline_state {
struct anv_push_constants push_constants; struct anv_push_constants push_constants;
/** Tracks whether the push constant data has changed and need to be reemitted */
bool push_constants_data_dirty;
/* Push constant state allocated when flushing push constants. */ /* Push constant state allocated when flushing push constants. */
struct anv_state push_constants_state; struct anv_state push_constants_state;
@ -3743,6 +3746,7 @@ struct anv_cmd_state {
VkShaderStageFlags descriptors_dirty; VkShaderStageFlags descriptors_dirty;
VkShaderStageFlags push_descriptors_dirty; VkShaderStageFlags push_descriptors_dirty;
/** Tracks the 3DSTATE_CONSTANT_* instruction that needs to be reemitted */
VkShaderStageFlags push_constants_dirty; VkShaderStageFlags push_constants_dirty;
struct { struct {

View File

@ -394,6 +394,7 @@ genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer *cmd_buffer)
* state heap. If we change it, we need to reemit the push constants. * state heap. If we change it, we need to reemit the push constants.
*/ */
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
cmd_buffer->state.compute.base.push_constants_data_dirty = true;
#endif #endif
} }
} }
@ -2751,6 +2752,7 @@ genX(flush_descriptor_buffers)(struct anv_cmd_buffer *cmd_buffer,
cmd_buffer->state.push_constants_dirty |= cmd_buffer->state.push_constants_dirty |=
(cmd_buffer->state.descriptor_buffers.offsets_dirty & (cmd_buffer->state.descriptor_buffers.offsets_dirty &
pipe_state->pipeline->active_stages); pipe_state->pipeline->active_stages);
pipe_state->push_constants_data_dirty = true;
cmd_buffer->state.descriptor_buffers.offsets_dirty &= cmd_buffer->state.descriptor_buffers.offsets_dirty &=
~pipe_state->pipeline->active_stages; ~pipe_state->pipeline->active_stages;
} }
@ -2943,6 +2945,7 @@ genX(BeginCommandBuffer)(
* flag them dirty here to make sure they get emitted. * flag them dirty here to make sure they get emitted.
*/ */
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_ALL_GRAPHICS; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_ALL_GRAPHICS;
cmd_buffer->state.gfx.base.push_constants_data_dirty = true;
if (cmd_buffer->usage_flags & if (cmd_buffer->usage_flags &
VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) {

View File

@ -138,6 +138,7 @@ genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer)
* so flag push constants as dirty if we change the pipeline. * so flag push constants as dirty if we change the pipeline.
*/ */
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
comp_state->base.push_constants_data_dirty = true;
} }
cmd_buffer->state.descriptors_dirty |= cmd_buffer->state.descriptors_dirty |=
@ -179,8 +180,13 @@ genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer)
} }
if (cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_COMPUTE_BIT) { if (cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_COMPUTE_BIT) {
comp_state->push_data =
anv_cmd_buffer_cs_push_constants(cmd_buffer); if (comp_state->push_data.alloc_size == 0 ||
comp_state->base.push_constants_data_dirty) {
comp_state->push_data =
anv_cmd_buffer_cs_push_constants(cmd_buffer);
comp_state->base.push_constants_data_dirty = false;
}
#if GFX_VERx10 < 125 #if GFX_VERx10 < 125
if (comp_state->push_data.alloc_size) { if (comp_state->push_data.alloc_size) {
@ -218,6 +224,7 @@ anv_cmd_buffer_push_base_group_id(struct anv_cmd_buffer *cmd_buffer,
push->cs.base_work_group_id[2] = baseGroupZ; push->cs.base_work_group_id[2] = baseGroupZ;
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
cmd_buffer->state.compute.base.push_constants_data_dirty = true;
} }
} }

View File

@ -486,10 +486,12 @@ cmd_buffer_flush_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer,
} }
} }
/* Resets the push constant state so that we allocate a new one if /* Setting NULL resets the push constant state so that we allocate a new one
* needed. * if needed. If push constant data not dirty, get_push_range_address can
* re-use existing allocation.
*/ */
gfx_state->base.push_constants_state = ANV_STATE_NULL; if (gfx_state->base.push_constants_data_dirty)
gfx_state->base.push_constants_state = ANV_STATE_NULL;
anv_foreach_stage(stage, dirty_stages) { anv_foreach_stage(stage, dirty_stages) {
unsigned buffer_count = 0; unsigned buffer_count = 0;
@ -560,6 +562,7 @@ cmd_buffer_flush_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer,
#endif #endif
cmd_buffer->state.push_constants_dirty &= ~flushed; cmd_buffer->state.push_constants_dirty &= ~flushed;
gfx_state->base.push_constants_data_dirty = false;
} }
#if GFX_VERx10 >= 125 #if GFX_VERx10 >= 125

View File

@ -1343,6 +1343,7 @@ genX(cmd_buffer_flush_gfx_runtime_state)(struct anv_cmd_buffer *cmd_buffer)
push->gfx.tcs_input_vertices != dyn->ts.patch_control_points) { push->gfx.tcs_input_vertices != dyn->ts.patch_control_points) {
push->gfx.tcs_input_vertices = dyn->ts.patch_control_points; push->gfx.tcs_input_vertices = dyn->ts.patch_control_points;
cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
gfx->base.push_constants_data_dirty = true;
} }
#undef GET #undef GET