From fc8d2543fc654acacac1f80203e4646ad4c238af Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Fri, 25 Mar 2022 17:36:35 -0500 Subject: [PATCH] vulkan,v3dv: Add a driver_internal flag to vk_image_view_init/create We already had a little workaround for v3dv where, for some if its meta ops, it had to bind a depth/stenicil image as color. Instead of special-casing binding depth/stencil as color, let's flip on the drier_internal flag and get rid of most of the checks in that case. Reviewed-by: Iago Toral Quiroga Part-of: --- src/broadcom/vulkan/v3dv_image.c | 9 ++-- src/gallium/frontends/lavapipe/lvp_image.c | 3 +- src/imagination/vulkan/pvr_image.c | 1 + src/intel/vulkan/anv_image.c | 2 +- src/panfrost/vulkan/panvk_vX_image.c | 2 +- src/vulkan/runtime/vk_image.c | 74 ++++++++++++++++-------------- src/vulkan/runtime/vk_image.h | 2 + 7 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index 5cb0237..ae13eff 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -493,6 +493,7 @@ v3dv_image_type_to_view_type(VkImageType type) static VkResult create_image_view(struct v3dv_device *device, + bool driver_internal, const VkImageViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkImageView *pView) @@ -500,8 +501,8 @@ create_image_view(struct v3dv_device *device, V3DV_FROM_HANDLE(v3dv_image, image, pCreateInfo->image); struct v3dv_image_view *iview; - iview = vk_image_view_create(&device->vk, pCreateInfo, pAllocator, - sizeof(*iview)); + iview = vk_image_view_create(&device->vk, driver_internal, pCreateInfo, + pAllocator, sizeof(*iview)); if (iview == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); @@ -566,7 +567,7 @@ v3dv_create_image_view(struct v3dv_device *device, const VkImageViewCreateInfo *pCreateInfo, VkImageView *pView) { - return create_image_view(device, pCreateInfo, NULL, pView); + return create_image_view(device, true, pCreateInfo, NULL, pView); } VKAPI_ATTR VkResult VKAPI_CALL @@ -577,7 +578,7 @@ v3dv_CreateImageView(VkDevice _device, { V3DV_FROM_HANDLE(v3dv_device, device, _device); - return create_image_view(device, pCreateInfo, pAllocator, pView); + return create_image_view(device, false, pCreateInfo, pAllocator, pView); } VKAPI_ATTR void VKAPI_CALL diff --git a/src/gallium/frontends/lavapipe/lvp_image.c b/src/gallium/frontends/lavapipe/lvp_image.c index df2a519..6bdad66 100644 --- a/src/gallium/frontends/lavapipe/lvp_image.c +++ b/src/gallium/frontends/lavapipe/lvp_image.c @@ -178,7 +178,8 @@ lvp_CreateImageView(VkDevice _device, LVP_FROM_HANDLE(lvp_image, image, pCreateInfo->image); struct lvp_image_view *view; - view = vk_image_view_create(&device->vk, pCreateInfo, pAllocator, sizeof(*view)); + view = vk_image_view_create(&device->vk, false, pCreateInfo, + pAllocator, sizeof(*view)); if (view == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); diff --git a/src/imagination/vulkan/pvr_image.c b/src/imagination/vulkan/pvr_image.c index d823326..fede18c 100644 --- a/src/imagination/vulkan/pvr_image.c +++ b/src/imagination/vulkan/pvr_image.c @@ -264,6 +264,7 @@ VkResult pvr_CreateImageView(VkDevice _device, VkResult result; iview = vk_image_view_create(&device->vk, + false /* driver_internal */, pCreateInfo, pAllocator, sizeof(*iview)); diff --git a/src/intel/vulkan/anv_image.c b/src/intel/vulkan/anv_image.c index 62d14cc..f16cd45 100644 --- a/src/intel/vulkan/anv_image.c +++ b/src/intel/vulkan/anv_image.c @@ -2526,7 +2526,7 @@ anv_CreateImageView(VkDevice _device, ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); struct anv_image_view *iview; - iview = vk_image_view_create(&device->vk, pCreateInfo, + iview = vk_image_view_create(&device->vk, false, pCreateInfo, pAllocator, sizeof(*iview)); if (iview == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); diff --git a/src/panfrost/vulkan/panvk_vX_image.c b/src/panfrost/vulkan/panvk_vX_image.c index efd215b..67c087d 100644 --- a/src/panfrost/vulkan/panvk_vX_image.c +++ b/src/panfrost/vulkan/panvk_vX_image.c @@ -97,7 +97,7 @@ panvk_per_arch(CreateImageView)(VkDevice _device, VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image); struct panvk_image_view *view; - view = vk_image_view_create(&device->vk, pCreateInfo, + view = vk_image_view_create(&device->vk, false, pCreateInfo, pAllocator, sizeof(*view)); if (view == NULL) return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); diff --git a/src/vulkan/runtime/vk_image.c b/src/vulkan/runtime/vk_image.c index f01998a..e649618 100644 --- a/src/vulkan/runtime/vk_image.c +++ b/src/vulkan/runtime/vk_image.c @@ -259,6 +259,7 @@ remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component) void vk_image_view_init(struct vk_device *device, struct vk_image_view *image_view, + bool driver_internal, const VkImageViewCreateInfo *pCreateInfo) { vk_object_base_init(device, &image_view->base, VK_OBJECT_TYPE_IMAGE_VIEW); @@ -271,42 +272,47 @@ vk_image_view_init(struct vk_device *device, image_view->view_type = pCreateInfo->viewType; image_view->format = pCreateInfo->format; - switch (image_view->view_type) { - case VK_IMAGE_VIEW_TYPE_1D: - case VK_IMAGE_VIEW_TYPE_1D_ARRAY: - assert(image->image_type == VK_IMAGE_TYPE_1D); - break; - case VK_IMAGE_VIEW_TYPE_2D: - case VK_IMAGE_VIEW_TYPE_2D_ARRAY: - if (image->create_flags & (VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT)) + if (!driver_internal) { + switch (image_view->view_type) { + case VK_IMAGE_VIEW_TYPE_1D: + case VK_IMAGE_VIEW_TYPE_1D_ARRAY: + assert(image->image_type == VK_IMAGE_TYPE_1D); + break; + case VK_IMAGE_VIEW_TYPE_2D: + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: + if (image->create_flags & (VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT | + VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT)) + assert(image->image_type == VK_IMAGE_TYPE_3D); + else + assert(image->image_type == VK_IMAGE_TYPE_2D); + break; + case VK_IMAGE_VIEW_TYPE_3D: assert(image->image_type == VK_IMAGE_TYPE_3D); - else + break; + case VK_IMAGE_VIEW_TYPE_CUBE: + case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: assert(image->image_type == VK_IMAGE_TYPE_2D); - break; - case VK_IMAGE_VIEW_TYPE_3D: - assert(image->image_type == VK_IMAGE_TYPE_3D); - break; - case VK_IMAGE_VIEW_TYPE_CUBE: - case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: - assert(image->image_type == VK_IMAGE_TYPE_2D); - assert(image->create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); - break; - default: - unreachable("Invalid image view type"); + assert(image->create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT); + break; + default: + unreachable("Invalid image view type"); + } } const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; - /* Some drivers may want to create color views of depth/stencil images - * to implement certain operations, which is not strictly allowed by the - * Vulkan spec, so handle this case separately. - */ - bool is_color_view_of_depth_stencil = - vk_format_is_depth_or_stencil(image->format) && - vk_format_is_color(pCreateInfo->format); - if (is_color_view_of_depth_stencil) { - assert(util_format_get_blocksize(vk_format_to_pipe_format(image->format)) == - util_format_get_blocksize(vk_format_to_pipe_format(pCreateInfo->format))); + if (driver_internal) { + /* For driver internal images, all we require is that the block sizes + * match. Otherwise, we trust the driver to use a format it knows what + * to do with. Combined depth/stencil images might not match if the + * driver only cares about one of the two aspects. + */ + if (image->aspects == VK_IMAGE_ASPECT_COLOR_BIT || + image->aspects == VK_IMAGE_ASPECT_DEPTH_BIT || + image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT) { + assert(vk_format_get_blocksize(image->format) == + vk_format_get_blocksize(image_view->format)); + } image_view->aspects = range->aspectMask; image_view->view_format = pCreateInfo->format; } else { @@ -411,13 +417,12 @@ vk_image_view_init(struct vk_device *device, /* If we are creating a color view from a depth/stencil image we compute * usage from the underlying depth/stencil aspects. */ - const VkImageUsageFlags image_usage = is_color_view_of_depth_stencil ? - vk_image_usage(image, image->aspects) : + const VkImageUsageFlags image_usage = vk_image_usage(image, image_view->aspects); const VkImageViewUsageCreateInfo *usage_info = vk_find_struct_const(pCreateInfo, IMAGE_VIEW_USAGE_CREATE_INFO); image_view->usage = usage_info ? usage_info->usage : image_usage; - assert(!(image_view->usage & ~image_usage)); + assert(driver_internal || !(image_view->usage & ~image_usage)); } void @@ -428,6 +433,7 @@ vk_image_view_finish(struct vk_image_view *image_view) void * vk_image_view_create(struct vk_device *device, + bool driver_internal, const VkImageViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *alloc, size_t size) @@ -438,7 +444,7 @@ vk_image_view_create(struct vk_device *device, if (image_view == NULL) return NULL; - vk_image_view_init(device, image_view, pCreateInfo); + vk_image_view_init(device, image_view, driver_internal, pCreateInfo); return image_view; } diff --git a/src/vulkan/runtime/vk_image.h b/src/vulkan/runtime/vk_image.h index f6b3f87..58e32ad 100644 --- a/src/vulkan/runtime/vk_image.h +++ b/src/vulkan/runtime/vk_image.h @@ -213,10 +213,12 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vk_image_view, base, VkImageView, void vk_image_view_init(struct vk_device *device, struct vk_image_view *image_view, + bool driver_internal, const VkImageViewCreateInfo *pCreateInfo); void vk_image_view_finish(struct vk_image_view *image_view); void *vk_image_view_create(struct vk_device *device, + bool driver_internal, const VkImageViewCreateInfo *pCreateInfo, const VkAllocationCallbacks *alloc, size_t size); -- 2.7.4