From 2d627f28c8fb55336d001846cfe70877b446d978 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Sat, 7 Jan 2023 02:54:44 +0200 Subject: [PATCH] anv: use the null surface with unused push descriptor binding table entries Some binding table entries have been identify as unused in the shaders by the push constant analysis pass. We can just put the null entry in there. Signed-off-by: Lionel Landwerlin Fixes: b49b18f0b7 ("anv: reduce BT emissions & surface state writes with push descriptors") Reviewed-by: Emma Anholt Part-of: --- src/intel/vulkan/genX_cmd_buffer.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 3f20836c237..8914c831f3c 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -2048,11 +2048,20 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, } case ANV_DESCRIPTOR_SET_DESCRIPTORS: { + struct anv_descriptor_set *set = + pipe_state->descriptors[binding->index]; + + /* If the shader doesn't access the set buffer, just put the null + * surface. + */ + if (set->is_push && !shader->push_desc_info.used_set_buffer) { + bt_map[s] = 0; + break; + } + /* This is a descriptor set buffer so the set index is actually * given by binding->binding. (Yes, that's confusing.) */ - struct anv_descriptor_set *set = - pipe_state->descriptors[binding->index]; assert(set->desc_mem.alloc_size); assert(set->desc_surface_state.alloc_size); bt_map[s] = set->desc_surface_state.offset + state_offset; @@ -2065,6 +2074,7 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, assert(binding->set < MAX_SETS); const struct anv_descriptor_set *set = pipe_state->descriptors[binding->set]; + if (binding->index >= set->descriptor_count) { /* From the Vulkan spec section entitled "DescriptorSet and * Binding Assignment": @@ -2081,6 +2091,21 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer, assert(binding->index < set->layout->descriptor_count); continue; } + + /* For push descriptor, if the binding is fully promoted to push + * constants, just reference the null surface in the binding table. + * It's unused and we didn't allocate/pack a surface state for it . + */ + if (set->is_push) { + uint32_t desc_idx = set->layout->binding[binding->binding].descriptor_index; + assert(desc_idx < MAX_PUSH_DESCRIPTORS); + + if (shader->push_desc_info.fully_promoted_ubo_descriptors & BITFIELD_BIT(desc_idx)) { + surface_state = cmd_buffer->device->null_surface_state; + break; + } + } + const struct anv_descriptor *desc = &set->descriptors[binding->index]; /* Relative offset in the STATE_BASE_ADDRESS::SurfaceStateBaseAddress * heap. Depending on where the descriptor surface state is