anv: factor out descriptor buffer flushing

Take the opportunity to fix the flush of the descriptor buffer surface
when needed. Previously we would only flush it if the shader used one
of the push descriptor.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27504>
This commit is contained in:
Lionel Landwerlin
2024-02-05 18:07:14 +02:00
committed by Marge Bot
parent cf193af762
commit dbee85713f
5 changed files with 104 additions and 64 deletions
+13 -2
View File
@@ -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);
}
}
}
+51 -4
View File
@@ -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;
}
+29 -29
View File
@@ -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
+7 -19
View File
@@ -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.
+4 -10
View File
@@ -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 ||