From 1c567ae3a2f2bad5badafc4f2e3615d719500ef5 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 1 Jul 2022 19:58:48 +0200 Subject: [PATCH] dzn: Hook-up format-casting This was only partially supported, with not way to cross D3D12 old compatibility boundary. With the RelaxedFormatCastingSupported feature, we can cast any format to any other format with the same block size, which maps pretty well to how Vulkan see things. Reviewed-by: Jesse Natalie Part-of: --- src/microsoft/vulkan/dzn_image.c | 71 +++++++++++++++++++++++++++--- src/microsoft/vulkan/dzn_private.h | 2 + 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/microsoft/vulkan/dzn_image.c b/src/microsoft/vulkan/dzn_image.c index 8fcf4a8c4c6..b356369024c 100644 --- a/src/microsoft/vulkan/dzn_image.c +++ b/src/microsoft/vulkan/dzn_image.c @@ -68,14 +68,39 @@ dzn_image_create(struct dzn_device *device, const VkAllocationCallbacks *pAllocator, VkImage *out) { - struct dzn_image *image = - vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*image), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk); + VkFormat *compat_formats = NULL; + uint32_t compat_format_count = 0; - if (!image) + if (pdev->options12.RelaxedFormatCastingSupported) { + VkResult ret = + vk_image_create_get_format_list(&device->vk, pCreateInfo, pAllocator, + &compat_formats, &compat_format_count); + if (ret != VK_SUCCESS) + return ret; + } + + VK_MULTIALLOC(ma); + VK_MULTIALLOC_DECL(&ma, struct dzn_image, image, 1); + VK_MULTIALLOC_DECL(&ma, DXGI_FORMAT, castable_formats, compat_format_count); + + if (!vk_multialloc_zalloc2(&ma, &device->vk.alloc, pAllocator, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) { + vk_free2(&device->vk.alloc, pAllocator, compat_formats); return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + image->castable_formats = castable_formats; + image->castable_format_count = 0; + for (uint32_t i = 0; i < compat_format_count; i++) { + castable_formats[image->castable_format_count] = + dzn_image_get_dxgi_format(compat_formats[i], pCreateInfo->usage, 0); + + if (castable_formats[image->castable_format_count] != DXGI_FORMAT_UNKNOWN) + image->castable_format_count++; + } + + vk_free2(&device->vk.alloc, pAllocator, compat_formats); #if 0 VkExternalMemoryHandleTypeFlags supported = @@ -153,6 +178,8 @@ dzn_image_create(struct dzn_device *device, image->desc.MipLevels = 1; image->desc.SampleDesc.Count = 1; image->desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + image->castable_formats = NULL; + image->castable_format_count = 0; } else { image->desc.Format = dzn_image_get_dxgi_format(pCreateInfo->format, @@ -169,7 +196,8 @@ dzn_image_create(struct dzn_device *device, image->desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; } - if (image->vk.create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) + if ((image->vk.create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && + !pdev->options12.RelaxedFormatCastingSupported) image->desc.Format = dzn_get_typeless_dxgi_format(image->desc.Format); if (image->desc.SampleDesc.Count > 1) @@ -708,13 +736,42 @@ dzn_BindImageMemory2(VkDevice dev, if (!did_bind) { image->mem = mem; image->mem_offset = bind_info->memoryOffset; - if (FAILED(ID3D12Device1_CreatePlacedResource(device->dev, mem->heap, + + HRESULT hres; + + if (device->dev10 && image->castable_format_count > 0) { + D3D12_RESOURCE_DESC1 desc = { + .Dimension = image->desc.Dimension, + .Alignment = image->desc.Alignment, + .Width = image->desc.Width, + .Height = image->desc.Height, + .DepthOrArraySize = image->desc.DepthOrArraySize, + .MipLevels = image->desc.MipLevels, + .Format = image->desc.Format, + .SampleDesc = image->desc.SampleDesc, + .Layout = image->desc.Layout, + .Flags = image->desc.Flags, + }; + + hres = ID3D12Device10_CreatePlacedResource2(device->dev10, mem->heap, + bind_info->memoryOffset, + &desc, + mem->initial_state, + NULL, + image->castable_format_count, + image->castable_formats, + &IID_ID3D12Resource, + (void **)&image->res); + } else { + hres = ID3D12Device1_CreatePlacedResource(device->dev, mem->heap, bind_info->memoryOffset, &image->desc, mem->initial_state, NULL, &IID_ID3D12Resource, - (void **)&image->res))) + (void **)&image->res); + } + if (FAILED(hres)) return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY); did_bind = true; } diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 4c5047c3b17..65f7aa403ed 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -883,6 +883,8 @@ struct dzn_image { ID3D12Resource *res; struct dzn_device_memory *mem; VkDeviceSize mem_offset; + uint32_t castable_format_count; + DXGI_FORMAT *castable_formats; }; bool