vulkan: Handle VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA automatically

This moves the bit into vk_image.h and handles it automatically in
vk_image_view_init() so drivers don't have to.

This also means that Meta is now hitting the driver_internal path for
all its images so we need to do the same format fixups there that we
sould normally do on the !driver_internal path.  We don't want to do
them unconditionally because v3dv and other drivers override
depth/stencil color formats and we don't want to break that.

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36957>
This commit is contained in:
Faith Ekstrand 2025-08-26 11:47:49 -04:00 committed by Marge Bot
parent e7b0cbdf40
commit 42abf00f2b
4 changed files with 19 additions and 10 deletions

View file

@ -520,13 +520,12 @@ pack_pbe(struct hk_device *dev, struct hk_image_view *view, unsigned view_plane,
static VkResult static VkResult
hk_image_view_init(struct hk_device *dev, struct hk_image_view *view, hk_image_view_init(struct hk_device *dev, struct hk_image_view *view,
bool driver_internal,
const VkImageViewCreateInfo *pCreateInfo) const VkImageViewCreateInfo *pCreateInfo)
{ {
VK_FROM_HANDLE(hk_image, image, pCreateInfo->image); VK_FROM_HANDLE(hk_image, image, pCreateInfo->image);
memset(view, 0, sizeof(*view)); memset(view, 0, sizeof(*view));
vk_image_view_init(&dev->vk, &view->vk, driver_internal, pCreateInfo); vk_image_view_init(&dev->vk, &view->vk, false, pCreateInfo);
/* First, figure out which image planes we need. For depth/stencil, we only /* First, figure out which image planes we need. For depth/stencil, we only
* have one aspect viewed at a time. * have one aspect viewed at a time.
@ -598,10 +597,7 @@ hk_CreateImageView(VkDevice _device, const VkImageViewCreateInfo *pCreateInfo,
if (!view) if (!view)
return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY); return vk_error(dev, VK_ERROR_OUT_OF_HOST_MEMORY);
result = hk_image_view_init( result = hk_image_view_init(dev, view, pCreateInfo);
dev, view,
pCreateInfo->flags & VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA,
pCreateInfo);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
hk_DestroyImageView(_device, hk_image_view_to_handle(view), pAllocator); hk_DestroyImageView(_device, hk_image_view_to_handle(view), pAllocator);
return result; return result;

View file

@ -304,12 +304,10 @@ panvk_per_arch(CreateImageView)(VkDevice _device,
{ {
VK_FROM_HANDLE(panvk_device, device, _device); VK_FROM_HANDLE(panvk_device, device, _device);
VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image); VK_FROM_HANDLE(panvk_image, image, pCreateInfo->image);
bool driver_internal =
(pCreateInfo->flags & VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA) != 0;
struct panvk_image_view *view; struct panvk_image_view *view;
VkResult result; VkResult result;
view = vk_image_view_create(&device->vk, driver_internal, pCreateInfo, view = vk_image_view_create(&device->vk, false, pCreateInfo,
pAllocator, sizeof(*view)); pAllocator, sizeof(*view));
if (view == NULL) if (view == NULL)
return panvk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); return panvk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);

View file

@ -443,6 +443,9 @@ vk_image_view_init(struct vk_device *device,
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO); assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
VK_FROM_HANDLE(vk_image, image, pCreateInfo->image); VK_FROM_HANDLE(vk_image, image, pCreateInfo->image);
if (pCreateInfo->flags & VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA)
driver_internal = true;
image_view->create_flags = pCreateInfo->flags; image_view->create_flags = pCreateInfo->flags;
image_view->image = image; image_view->image = image;
image_view->view_type = pCreateInfo->viewType; image_view->view_type = pCreateInfo->viewType;

View file

@ -27,6 +27,7 @@
#include "vk_buffer.h" #include "vk_buffer.h"
#include "vk_command_buffer.h" #include "vk_command_buffer.h"
#include "vk_device.h" #include "vk_device.h"
#include "vk_format.h"
#include "vk_pipeline.h" #include "vk_pipeline.h"
#include "vk_util.h" #include "vk_util.h"
@ -531,6 +532,7 @@ vk_meta_create_image_view(struct vk_command_buffer *cmd,
struct vk_device *device = cmd->base.device; struct vk_device *device = cmd->base.device;
const struct vk_device_dispatch_table *disp = &device->dispatch_table; const struct vk_device_dispatch_table *disp = &device->dispatch_table;
VkDevice _device = vk_device_to_handle(device); VkDevice _device = vk_device_to_handle(device);
VkImageViewCreateInfo patched_info = *info;
/* Meta must always specify view usage */ /* Meta must always specify view usage */
assert(vk_find_struct_const(info->pNext, IMAGE_VIEW_USAGE_CREATE_INFO)); assert(vk_find_struct_const(info->pNext, IMAGE_VIEW_USAGE_CREATE_INFO));
@ -538,7 +540,17 @@ vk_meta_create_image_view(struct vk_command_buffer *cmd,
/* Meta image views are always driver-internal */ /* Meta image views are always driver-internal */
assert(info->flags & VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA); assert(info->flags & VK_IMAGE_VIEW_CREATE_DRIVER_INTERNAL_BIT_MESA);
VkResult result = disp->CreateImageView(_device, info, NULL, image_view_out); /* vk_image_view_init() sanitizes depth/stencil formats to use the
* single-plane format, which drivers rely on. It doesn't do this with
* driver-internal images, though. We have to do that ourselves.
*/
if (info->subresourceRange.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
patched_info.format = vk_format_depth_only(info->format);
else if (info->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
patched_info.format = vk_format_stencil_only(info->format);
VkResult result =
disp->CreateImageView(_device, &patched_info, NULL, image_view_out);
if (unlikely(result != VK_SUCCESS)) if (unlikely(result != VK_SUCCESS))
return result; return result;