diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_buffer.c index 0c53d252d04..c7fe9f5e713 100644 --- a/src/intel/vulkan/anv_cmd_buffer.c +++ b/src/intel/vulkan/anv_cmd_buffer.c @@ -520,6 +520,26 @@ update_push_descriptor_flags(struct anv_cmd_pipeline_state *state, } } +static bool +maybe_update_dynamic_buffers_indices(struct anv_cmd_pipeline_state *state, + const uint8_t *offsets) +{ + struct anv_push_constants *push = &state->push_constants; + + bool modified = false; + for (uint32_t i = 0; i < MAX_SETS; i++) { + if ((push->desc_surface_offsets[i] & + ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK) != + offsets[i]) { + push->desc_surface_offsets[i] &= ~ANV_DESCRIPTOR_SET_DYNAMIC_INDEX_MASK; + push->desc_surface_offsets[i] |= offsets[i]; + modified = true; + } + } + + return modified; +} + static struct anv_cmd_pipeline_state * anv_cmd_buffer_get_pipeline_layout_state(struct anv_cmd_buffer *cmd_buffer, VkPipelineBindPoint bind_point, @@ -1259,6 +1279,12 @@ anv_cmd_buffer_set_rt_state(struct vk_command_buffer *vk_cmd_buffer, anv_cmd_buffer_set_rt_query_buffer(cmd_buffer, &rt->base, ray_queries, ANV_RT_STAGE_BITS); } + + if (maybe_update_dynamic_buffers_indices(&rt->base, + dynamic_descriptor_offsets)) { + cmd_buffer->state.push_constants_dirty |= ANV_RT_STAGE_BITS; + rt->base.push_constants_data_dirty = true; + } } void @@ -1550,6 +1576,7 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer, #undef diff_fix_state_stage #undef diff_var_state_stage + uint8_t dynamic_descriptors[MAX_SETS] = {}; for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) { struct anv_shader *shader = new_shaders[s]; @@ -1559,6 +1586,13 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer, ray_queries = MAX2(ray_queries, shader->vk.ray_queries); if (gfx->shaders[s] != shader) set_dirty_for_bind_map(cmd_buffer, s, &shader->bind_map); + + for (uint32_t i = 0; i < MAX_SETS; i++) { + assert(dynamic_descriptors[i] == 0 || + dynamic_descriptors[i] == + shader->bind_map.dynamic_descriptors[i]); + dynamic_descriptors[i] = shader->bind_map.dynamic_descriptors[i]; + } } if (gfx->shaders[s] != shader) @@ -1683,10 +1717,22 @@ bind_graphics_shaders(struct anv_cmd_buffer *cmd_buffer, cmd_buffer->state.gfx.shaders, ARRAY_SIZE(cmd_buffer->state.gfx.shaders)); + uint8_t dynamic_descriptor_count = 0; + uint8_t dynamic_descriptor_offsets[MAX_SETS] = {}; + for (uint32_t i = 0; i < MAX_SETS; i++) { + dynamic_descriptor_offsets[i] = dynamic_descriptor_count; + dynamic_descriptor_count += dynamic_descriptors[i]; + } + if (maybe_update_dynamic_buffers_indices(&gfx->base, + dynamic_descriptor_offsets)) { + cmd_buffer->state.push_constants_dirty |= gfx->active_stages; + gfx->base.push_constants_data_dirty = true; + } + if (ray_queries > 0) { assert(cmd_buffer->device->info->verx10 >= 125); anv_cmd_buffer_set_rt_query_buffer(cmd_buffer, &gfx->base, ray_queries, - cmd_buffer->state.gfx.active_stages); + gfx->active_stages); } } diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 71a0d5f2310..432879ca6f8 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -1175,6 +1175,9 @@ struct anv_pipeline_bind_map { BITSET_DECLARE(input_attachments, MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS + 1); struct anv_push_range push_ranges[4]; + + /* Number of dynamic descriptor in each set */ + uint8_t dynamic_descriptors[MAX_SETS]; }; struct anv_push_descriptor_info { diff --git a/src/intel/vulkan/anv_shader.c b/src/intel/vulkan/anv_shader.c index 4a13a4cb2e2..f47a47b34a9 100644 --- a/src/intel/vulkan/anv_shader.c +++ b/src/intel/vulkan/anv_shader.c @@ -82,6 +82,8 @@ anv_shader_deserialize(struct vk_device *vk_device, blob_copy_bytes(blob, data.bind_map.input_attachments, sizeof(data.bind_map.input_attachments)); blob_copy_bytes(blob, data.bind_map.push_ranges, sizeof(data.bind_map.push_ranges)); + blob_copy_bytes(blob, data.bind_map.dynamic_descriptors, + sizeof(data.bind_map.dynamic_descriptors)); if (blob->overrun) return vk_error(device, VK_ERROR_UNKNOWN); @@ -159,6 +161,8 @@ anv_shader_serialize(struct vk_device *device, sizeof(shader->bind_map.input_attachments)); blob_write_bytes(blob, shader->bind_map.push_ranges, sizeof(shader->bind_map.push_ranges)); + blob_write_bytes(blob, shader->bind_map.dynamic_descriptors, + sizeof(shader->bind_map.dynamic_descriptors)); return !blob->out_of_memory; } diff --git a/src/intel/vulkan/anv_shader.h b/src/intel/vulkan/anv_shader.h index 5bfb54ae5d9..cffe4286fce 100644 --- a/src/intel/vulkan/anv_shader.h +++ b/src/intel/vulkan/anv_shader.h @@ -108,6 +108,8 @@ struct anv_shader_data { struct anv_pipeline_push_map push_map; + uint8_t dynamic_descriptors[MAX_SETS]; + bool uses_bt_for_push_descs; unsigned *code; diff --git a/src/intel/vulkan/anv_shader_compile.c b/src/intel/vulkan/anv_shader_compile.c index 818841405c6..58332976fca 100644 --- a/src/intel/vulkan/anv_shader_compile.c +++ b/src/intel/vulkan/anv_shader_compile.c @@ -1900,6 +1900,12 @@ anv_shader_compile(struct vk_device *vk_device, shader_data->source_hash = ((uint32_t*)info->nir->info.source_blake3)[0]; + for (uint32_t i = 0; i < info->set_layout_count; i++) { + shader_data->dynamic_descriptors[i] = + info->set_layouts[i] != NULL ? + info->set_layouts[i]->dynamic_descriptor_count : 0; + } + shader_data->bind_map.layout_type = set_layouts_get_layout_type((struct anv_descriptor_set_layout * const *)info->set_layouts, info->set_layout_count);