diff --git a/src/intel/vulkan/anv_descriptor_set.c b/src/intel/vulkan/anv_descriptor_set.c index 9c5ed358e0b..df6572a2134 100644 --- a/src/intel/vulkan/anv_descriptor_set.c +++ b/src/intel/vulkan/anv_descriptor_set.c @@ -1906,6 +1906,11 @@ anv_push_descriptor_set_init(struct anv_cmd_buffer *cmd_buffer, set->desc_sampler_mem); } + if (push_set->set_used_on_gpu) { + set->desc_surface_state = ANV_STATE_NULL; + push_set->set_used_on_gpu = false; + } + return true; } @@ -2306,10 +2311,16 @@ anv_descriptor_set_write_buffer(struct anv_device *device, bview->vk.range = desc->bind_range; bview->address = bind_addr; - if (set->is_push) + if (set->is_push) { set->generate_surface_states |= BITFIELD_BIT(descriptor_index); - else + /* Reset the surface state to make sure + * genX(cmd_buffer_emit_push_descriptor_surfaces) generates a new + * one. + */ + bview->general.state = ANV_STATE_NULL; + } else { anv_descriptor_write_surface_state(device, desc, bview->general.state); + } } } diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h index 0b81795946e..0427700fbfb 100644 --- a/src/intel/vulkan/anv_genX.h +++ b/src/intel/vulkan/anv_genX.h @@ -151,10 +151,6 @@ genX(cmd_buffer_flush_descriptor_sets)(struct anv_cmd_buffer *cmd_buffer, const VkShaderStageFlags dirty, struct anv_shader_bin **shaders, uint32_t num_shaders); -void -genX(cmd_buffer_flush_push_descriptor_set)(struct anv_cmd_buffer *cmd_buffer, - struct anv_cmd_pipeline_state *state, - struct anv_pipeline *pipeline); void genX(cmd_buffer_flush_gfx_hw_state)(struct anv_cmd_buffer *cmd_buffer); @@ -327,3 +323,54 @@ genX(emit_simple_shader_end)(struct anv_simple_shader *state); VkResult genX(init_trtt_context_state)(struct anv_queue *queue); VkResult genX(write_trtt_entries)(struct anv_trtt_submission *submit); + +void +genX(cmd_buffer_emit_push_descriptor_buffer_surface)(struct anv_cmd_buffer *cmd_buffer, + struct anv_descriptor_set *set); + +void +genX(cmd_buffer_emit_push_descriptor_surfaces)(struct anv_cmd_buffer *cmd_buffer, + struct anv_descriptor_set *set); + +static inline VkShaderStageFlags +genX(cmd_buffer_flush_push_descriptors)(struct anv_cmd_buffer *cmd_buffer, + struct anv_cmd_pipeline_state *state, + struct anv_pipeline *pipeline) +{ + if (!pipeline->use_push_descriptor && !pipeline->use_push_descriptor_buffer) + return 0; + + assert(pipeline->layout.push_descriptor_set_index != -1); + struct anv_descriptor_set *set = + state->descriptors[pipeline->layout.push_descriptor_set_index]; + assert(set->is_push); + + const VkShaderStageFlags push_buffer_dirty = + cmd_buffer->state.push_descriptors_dirty & + pipeline->use_push_descriptor_buffer; + if (push_buffer_dirty) { + if (set->desc_surface_state.map == NULL) + genX(cmd_buffer_emit_push_descriptor_buffer_surface)(cmd_buffer, set); + + /* Force the next push descriptor update to allocate a new descriptor set. */ + state->push_descriptor.set_used_on_gpu = true; + } + + const VkShaderStageFlags push_descriptor_dirty = + cmd_buffer->state.push_descriptors_dirty & pipeline->use_push_descriptor; + if (push_descriptor_dirty) { + genX(cmd_buffer_emit_push_descriptor_surfaces)(cmd_buffer, set); + + /* Force the next push descriptor update to allocate a new descriptor set. */ + state->push_descriptor.set_used_on_gpu = true; + } + + /* Clear the dirty stages now that we've generated the surface states for + * them. + */ + cmd_buffer->state.push_descriptors_dirty &= + ~(push_descriptor_dirty | push_buffer_dirty); + + /* Return the binding table stages that need to be updated */ + return push_buffer_dirty | push_descriptor_dirty; +} diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 92f9252f7c5..e7a0bf0c225 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -2262,27 +2262,47 @@ genX(cmd_buffer_flush_descriptor_sets)(struct anv_cmd_buffer *cmd_buffer, return flushed; } +/* This function generates the surface state used to read the content of the + * descriptor buffer. + */ +void +genX(cmd_buffer_emit_push_descriptor_buffer_surface)(struct anv_cmd_buffer *cmd_buffer, + struct anv_descriptor_set *set) +{ + assert(set->desc_surface_state.map == NULL); + + struct anv_descriptor_set_layout *layout = set->layout; + enum isl_format format = + anv_isl_format_for_descriptor_type(cmd_buffer->device, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + + set->desc_surface_state = + anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1); + if (set->desc_surface_state.map == NULL) + return; + anv_fill_buffer_surface_state(cmd_buffer->device, + set->desc_surface_state.map, + format, ISL_SWIZZLE_IDENTITY, + ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, + set->desc_surface_addr, + layout->descriptor_buffer_surface_size, 1); +} + /* This functions generates surface states used by a pipeline for push * descriptors. This is delayed to the draw/dispatch time to avoid allocation * and surface state generation when a pipeline is not going to use the * binding table to access any push descriptor data. */ void -genX(cmd_buffer_flush_push_descriptor_set)(struct anv_cmd_buffer *cmd_buffer, - struct anv_cmd_pipeline_state *state, - struct anv_pipeline *pipeline) +genX(cmd_buffer_emit_push_descriptor_surfaces)(struct anv_cmd_buffer *cmd_buffer, + struct anv_descriptor_set *set) { - assert(pipeline->use_push_descriptor && - pipeline->layout.push_descriptor_set_index != -1); - - struct anv_descriptor_set *set = - state->descriptors[pipeline->layout.push_descriptor_set_index]; while (set->generate_surface_states) { int desc_idx = u_bit_scan(&set->generate_surface_states); struct anv_descriptor *desc = &set->descriptors[desc_idx]; struct anv_buffer_view *bview = desc->set_buffer_view; - if (bview != NULL) { + if (bview != NULL && bview->general.state.map == NULL) { bview->general.state = anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1); if (bview->general.state.map == NULL) @@ -2291,26 +2311,6 @@ genX(cmd_buffer_flush_push_descriptor_set)(struct anv_cmd_buffer *cmd_buffer, bview->general.state); } } - - if (pipeline->use_push_descriptor_buffer) { - struct anv_descriptor_set_layout *layout = set->layout; - enum isl_format format = - anv_isl_format_for_descriptor_type(cmd_buffer->device, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - - set->desc_surface_state = - anv_cmd_buffer_alloc_surface_states(cmd_buffer, 1); - if (set->desc_surface_state.map == NULL) - return; - anv_fill_buffer_surface_state(cmd_buffer->device, - set->desc_surface_state.map, - format, ISL_SWIZZLE_IDENTITY, - ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, - set->desc_surface_addr, - layout->descriptor_buffer_surface_size, 1); - } - - state->push_descriptor.set_used_on_gpu = true; } ALWAYS_INLINE void diff --git a/src/intel/vulkan/genX_cmd_compute.c b/src/intel/vulkan/genX_cmd_compute.c index e3c12d0b682..33561a68d19 100644 --- a/src/intel/vulkan/genX_cmd_compute.c +++ b/src/intel/vulkan/genX_cmd_compute.c @@ -138,16 +138,10 @@ genX(cmd_buffer_flush_compute_state)(struct anv_cmd_buffer *cmd_buffer) cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; } - const uint32_t push_descriptor_dirty = - cmd_buffer->state.push_descriptors_dirty & - pipeline->base.use_push_descriptor; - if (push_descriptor_dirty) { - genX(cmd_buffer_flush_push_descriptor_set)(cmd_buffer, - &cmd_buffer->state.compute.base, - &pipeline->base); - cmd_buffer->state.descriptors_dirty |= push_descriptor_dirty; - cmd_buffer->state.push_descriptors_dirty &= ~push_descriptor_dirty; - } + cmd_buffer->state.descriptors_dirty |= + genX(cmd_buffer_flush_push_descriptors)(cmd_buffer, + &cmd_buffer->state.compute.base, + &pipeline->base); if ((cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) || cmd_buffer->state.compute.pipeline_dirty) { @@ -889,15 +883,9 @@ cmd_buffer_trace_rays(struct anv_cmd_buffer *cmd_buffer, genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); - const VkShaderStageFlags push_descriptor_dirty = - cmd_buffer->state.push_descriptors_dirty & - pipeline->base.use_push_descriptor; - if (push_descriptor_dirty) { - genX(cmd_buffer_flush_push_descriptor_set)(cmd_buffer, - &cmd_buffer->state.rt.base, - &pipeline->base); - cmd_buffer->state.push_descriptors_dirty &= ~push_descriptor_dirty; - } + genX(cmd_buffer_flush_push_descriptors)(cmd_buffer, + &cmd_buffer->state.rt.base, + &pipeline->base); /* Add these to the reloc list as they're internal buffers that don't * actually have relocs to pick them up manually. diff --git a/src/intel/vulkan/genX_cmd_draw.c b/src/intel/vulkan/genX_cmd_draw.c index 85801bebb71..37796f35626 100644 --- a/src/intel/vulkan/genX_cmd_draw.c +++ b/src/intel/vulkan/genX_cmd_draw.c @@ -760,16 +760,10 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer) uint32_t descriptors_dirty = cmd_buffer->state.descriptors_dirty & pipeline->base.base.active_stages; - const uint32_t push_descriptor_dirty = - cmd_buffer->state.push_descriptors_dirty & - pipeline->base.base.use_push_descriptor; - if (push_descriptor_dirty) { - genX(cmd_buffer_flush_push_descriptor_set)(cmd_buffer, - &cmd_buffer->state.gfx.base, - &pipeline->base.base); - descriptors_dirty |= push_descriptor_dirty; - cmd_buffer->state.push_descriptors_dirty &= ~push_descriptor_dirty; - } + descriptors_dirty |= + genX(cmd_buffer_flush_push_descriptors)(cmd_buffer, + &cmd_buffer->state.gfx.base, + &pipeline->base.base); /* Wa_1306463417, Wa_16011107343 - Send HS state for every primitive. */ if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE ||