Module: Mesa Branch: main Commit: d5841dce60603a6006c50348cd5c118c21a42aae URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=d5841dce60603a6006c50348cd5c118c21a42aae
Author: Chia-I Wu <[email protected]> Date: Mon Oct 9 14:16:19 2023 -0700 anv: support image views with surface state stream Add optional anv_state_stream to anv_image_view_init. This is useful for internal image views whose lifetimes are tied to the lifetime of a command buffer. Signed-off-by: Chia-I Wu <[email protected]> Reviewed-by: Lionel Landwerlin <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25467> --- src/intel/vulkan/anv_image.c | 51 ++++++++++++++++++++++---------------- src/intel/vulkan/anv_private.h | 14 +++++++++++ src/intel/vulkan/genX_cmd_buffer.c | 8 +++--- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index e63dd939f1a..4570ae0fd0a 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -2795,9 +2795,12 @@ anv_layout_has_untracked_aux_writes(const struct intel_device_info * const devin } static struct anv_state -maybe_alloc_surface_state(struct anv_device *device) +maybe_alloc_surface_state(struct anv_device *device, + struct anv_state_stream *surface_state_stream) { if (device->physical->indirect_descriptors) { + if (surface_state_stream) + return anv_state_stream_alloc(surface_state_stream, 64, 64); return anv_state_pool_alloc(&device->bindless_surface_state_pool, 64, 64); } else { return ANV_STATE_NULL; @@ -3092,16 +3095,18 @@ anv_can_fast_clear_color_view(struct anv_device *device, return true; } -static void +void anv_image_view_init(struct anv_device *device, struct anv_image_view *iview, - const VkImageViewCreateInfo *pCreateInfo) + const VkImageViewCreateInfo *pCreateInfo, + struct anv_state_stream *surface_state_stream) { ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); vk_image_view_init(&device->vk, &iview->vk, false, pCreateInfo); iview->image = image; iview->n_planes = anv_image_aspect_get_planes(iview->vk.aspects); + iview->use_surface_state_stream = surface_state_stream != NULL; /* Now go through the underlying image selected planes and map them to * planes in the image view. @@ -3143,9 +3148,9 @@ anv_image_view_init(struct anv_device *device, if (iview->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { iview->planes[vplane].optimal_sampler.state = - maybe_alloc_surface_state(device); + maybe_alloc_surface_state(device, surface_state_stream); iview->planes[vplane].general_sampler.state = - maybe_alloc_surface_state(device); + maybe_alloc_surface_state(device, surface_state_stream); enum isl_aux_usage general_aux_usage = anv_layout_to_aux_usage(device->info, image, 1UL << iaspect_bit, @@ -3193,7 +3198,7 @@ anv_image_view_init(struct anv_device *device, VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT); iview->planes[vplane].storage.state = - maybe_alloc_surface_state(device); + maybe_alloc_surface_state(device, surface_state_stream); anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, &storage_view, @@ -3205,26 +3210,28 @@ anv_image_view_init(struct anv_device *device, } } -static void +void anv_image_view_finish(struct anv_image_view *iview) { struct anv_device *device = container_of(iview->vk.base.device, struct anv_device, vk); - for (uint32_t plane = 0; plane < iview->n_planes; plane++) { - if (iview->planes[plane].optimal_sampler.state.alloc_size) { - anv_state_pool_free(&device->bindless_surface_state_pool, - iview->planes[plane].optimal_sampler.state); - } + if (!iview->use_surface_state_stream) { + for (uint32_t plane = 0; plane < iview->n_planes; plane++) { + if (iview->planes[plane].optimal_sampler.state.alloc_size) { + anv_state_pool_free(&device->bindless_surface_state_pool, + iview->planes[plane].optimal_sampler.state); + } - if (iview->planes[plane].general_sampler.state.alloc_size) { - anv_state_pool_free(&device->bindless_surface_state_pool, - iview->planes[plane].general_sampler.state); - } + if (iview->planes[plane].general_sampler.state.alloc_size) { + anv_state_pool_free(&device->bindless_surface_state_pool, + iview->planes[plane].general_sampler.state); + } - if (iview->planes[plane].storage.state.alloc_size) { - anv_state_pool_free(&device->bindless_surface_state_pool, - iview->planes[plane].storage.state); + if (iview->planes[plane].storage.state.alloc_size) { + anv_state_pool_free(&device->bindless_surface_state_pool, + iview->planes[plane].storage.state); + } } } @@ -3245,7 +3252,7 @@ anv_CreateImageView(VkDevice _device, if (iview == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - anv_image_view_init(device, iview, pCreateInfo); + anv_image_view_init(device, iview, pCreateInfo, NULL); *pView = anv_image_view_to_handle(iview); @@ -3315,7 +3322,7 @@ anv_CreateBufferView(VkDevice _device, view->address = anv_address_add(buffer->address, pCreateInfo->offset); if (buffer_usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { - view->general.state = maybe_alloc_surface_state(device); + view->general.state = maybe_alloc_surface_state(device, NULL); anv_fill_buffer_view_surface_state(device, &view->general, @@ -3328,7 +3335,7 @@ anv_CreateBufferView(VkDevice _device, } if (buffer_usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { - view->storage.state = maybe_alloc_surface_state(device); + view->storage.state = maybe_alloc_surface_state(device, NULL); anv_fill_buffer_view_surface_state(device, &view->storage, diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index 03897cd6694..c2a7bb4ca30 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -5001,6 +5001,13 @@ struct anv_image_view { const struct anv_image *image; /**< VkImageViewCreateInfo::image */ unsigned n_planes; + + /** + * True if the surface states (if any) are owned by some anv_state_stream + * from internal_surface_state_pool. + */ + bool use_surface_state_stream; + struct { struct isl_view isl; @@ -5070,6 +5077,13 @@ void anv_image_get_memory_requirements(struct anv_device *device, VkImageAspectFlags aspects, VkMemoryRequirements2 *pMemoryRequirements); +void anv_image_view_init(struct anv_device *device, + struct anv_image_view *iview, + const VkImageViewCreateInfo *pCreateInfo, + struct anv_state_stream *state_stream); + +void anv_image_view_finish(struct anv_image_view *iview); + enum isl_format anv_isl_format_for_descriptor_type(const struct anv_device *device, VkDescriptorType type); diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 66ec3361667..63fd078c90f 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -2042,7 +2042,8 @@ emit_indirect_descriptor_binding_table_entry(struct anv_cmd_buffer *cmd_buffer, (desc->layout == VK_IMAGE_LAYOUT_GENERAL) ? &desc->image_view->planes[binding->plane].general_sampler : &desc->image_view->planes[binding->plane].optimal_sampler; - surface_state = + surface_state = desc->image_view->use_surface_state_stream ? + sstate->state : anv_bindless_state_for_binding_table(device, sstate->state); assert(surface_state.alloc_size); } else { @@ -2055,8 +2056,9 @@ emit_indirect_descriptor_binding_table_entry(struct anv_cmd_buffer *cmd_buffer, if (desc->image_view) { const struct anv_surface_state *sstate = &desc->image_view->planes[binding->plane].storage; - surface_state = anv_bindless_state_for_binding_table( - device, sstate->state); + surface_state = desc->image_view->use_surface_state_stream ? + sstate->state : + anv_bindless_state_for_binding_table(device, sstate->state); assert(surface_state.alloc_size); } else { surface_state =
