diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index ac61c795b4d..55472d28d48 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -497,6 +497,7 @@ anv_cmd_buffer_set_ray_query_buffer(struct anv_cmd_buffer *cmd_buffer, pipeline_state->push_constants.ray_query_globals = anv_address_physical(ray_query_globals_addr); cmd_buffer->state.push_constants_dirty |= stages; + pipeline_state->push_constants_data_dirty = true; } /** @@ -696,14 +697,17 @@ void anv_CmdBindPipeline( modified = true; } } - if (modified) + if (modified) { cmd_buffer->state.push_constants_dirty |= stages; + state->push_constants_data_dirty = true; + } } 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; 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); @@ -922,6 +926,7 @@ anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer, else cmd_buffer->state.descriptors_dirty |= dirty_stages; cmd_buffer->state.push_constants_dirty |= dirty_stages; + pipe_state->push_constants_data_dirty = true; } #define ANV_GRAPHICS_STAGE_BITS \ @@ -1306,6 +1311,7 @@ void anv_CmdPushConstants2KHR( memcpy(pipe_state->push_constants.client_data + pInfo->offset, pInfo->pValues, pInfo->size); + pipe_state->push_constants_data_dirty = true; } if (pInfo->stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) { struct anv_cmd_pipeline_state *pipe_state = @@ -1313,6 +1319,7 @@ void anv_CmdPushConstants2KHR( memcpy(pipe_state->push_constants.client_data + pInfo->offset, pInfo->pValues, pInfo->size); + pipe_state->push_constants_data_dirty = true; } if (pInfo->stageFlags & ANV_RT_STAGE_BITS) { struct anv_cmd_pipeline_state *pipe_state = @@ -1320,6 +1327,7 @@ void anv_CmdPushConstants2KHR( memcpy(pipe_state->push_constants.client_data + pInfo->offset, pInfo->pValues, pInfo->size); + pipe_state->push_constants_data_dirty = true; } cmd_buffer->state.push_constants_dirty |= pInfo->stageFlags; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 185e2409b34..e22dbb65c74 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -3556,6 +3556,9 @@ struct anv_cmd_pipeline_state { 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. */ struct anv_state push_constants_state; @@ -3743,6 +3746,7 @@ struct anv_cmd_state { VkShaderStageFlags descriptors_dirty; VkShaderStageFlags push_descriptors_dirty; + /** Tracks the 3DSTATE_CONSTANT_* instruction that needs to be reemitted */ VkShaderStageFlags push_constants_dirty; struct { diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index eed57513cf9..f1c634c5d12 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -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. */ cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; + cmd_buffer->state.compute.base.push_constants_data_dirty = true; #endif } } @@ -2751,6 +2752,7 @@ genX(flush_descriptor_buffers)(struct anv_cmd_buffer *cmd_buffer, cmd_buffer->state.push_constants_dirty |= (cmd_buffer->state.descriptor_buffers.offsets_dirty & pipe_state->pipeline->active_stages); + pipe_state->push_constants_data_dirty = true; cmd_buffer->state.descriptor_buffers.offsets_dirty &= ~pipe_state->pipeline->active_stages; } @@ -2943,6 +2945,7 @@ genX(BeginCommandBuffer)( * flag them dirty here to make sure they get emitted. */ 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 & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT) { diff --git a/src/intel/vulkan/genX_cmd_compute.c b/src/intel/vulkan/genX_cmd_compute.c index ce1e7d9f2fb..7f05139e43f 100644 --- a/src/intel/vulkan/genX_cmd_compute.c +++ b/src/intel/vulkan/genX_cmd_compute.c @@ -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. */ cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; + comp_state->base.push_constants_data_dirty = true; } 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) { - 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 (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; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; + cmd_buffer->state.compute.base.push_constants_data_dirty = true; } } diff --git a/src/intel/vulkan/genX_cmd_draw.c b/src/intel/vulkan/genX_cmd_draw.c index 937ff0fc986..64a806659b6 100644 --- a/src/intel/vulkan/genX_cmd_draw.c +++ b/src/intel/vulkan/genX_cmd_draw.c @@ -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 - * needed. + /* Setting NULL resets the push constant state so that we allocate a new one + * 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) { unsigned buffer_count = 0; @@ -560,6 +562,7 @@ cmd_buffer_flush_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer, #endif cmd_buffer->state.push_constants_dirty &= ~flushed; + gfx_state->base.push_constants_data_dirty = false; } #if GFX_VERx10 >= 125 diff --git a/src/intel/vulkan/genX_gfx_state.c b/src/intel/vulkan/genX_gfx_state.c index 05e80423274..a9431cb947c 100644 --- a/src/intel/vulkan/genX_gfx_state.c +++ b/src/intel/vulkan/genX_gfx_state.c @@ -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; cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + gfx->base.push_constants_data_dirty = true; } #undef GET