[PATCH vkd3d 3/6] vkd3d: Use D32_SFLOAT_S8_UINT when D24_UNORM_S8_UINT is not supported.

Józef Kucia joseph.kucia at gmail.com
Tue May 7 08:37:03 CDT 2019


From: Józef Kucia <jkucia at codeweavers.com>

Fixes rendering in UE4 Infiltrator Demo on AMD.

Adjustments for depth bias aren't implemented yet.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 libs/vkd3d/command.c       | 12 +++++++++
 libs/vkd3d/device.c        |  8 +++++-
 libs/vkd3d/utils.c         | 53 ++++++++++++++++++++++++++++++++++++--
 libs/vkd3d/vkd3d_private.h |  5 ++++
 tests/d3d12.c              |  7 -----
 5 files changed, 75 insertions(+), 10 deletions(-)

diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 57415deb2ba3..abe4f27ecb24 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -3233,6 +3233,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
             return;
         }
 
+        if (dst_format->is_emulated)
+        {
+            FIXME("Format %#x is not supported yet.\n", dst_format->dxgi_format);
+            return;
+        }
+
         if ((dst_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
                 && (dst_format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT))
             FIXME("Depth-stencil format %#x not fully supported yet.\n", dst_format->dxgi_format);
@@ -3256,6 +3262,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
             return;
         }
 
+        if (src_format->is_emulated)
+        {
+            FIXME("Format %#x is not supported yet.\n", src_format->dxgi_format);
+            return;
+        }
+
         if ((src_format->vk_aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT)
                 && (src_format->vk_aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT))
             FIXME("Depth-stencil format %#x not fully supported yet.\n", src_format->dxgi_format);
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index f1ad09033ccd..a107e1e6414c 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1897,6 +1897,7 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface)
 
         vkd3d_private_store_destroy(&device->private_store);
 
+        vkd3d_cleanup_depth_stencil_formats(device);
         vkd3d_destroy_null_resources(&device->null_resources, device);
         vkd3d_gpu_va_allocator_cleanup(&device->gpu_va_allocator);
         vkd3d_render_pass_cache_cleanup(&device->render_pass_cache, device);
@@ -3090,9 +3091,12 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
     if (FAILED(hr = vkd3d_fence_worker_start(&device->fence_worker, device)))
         goto out_free_private_store;
 
-    if (FAILED(hr = vkd3d_init_null_resources(&device->null_resources, device)))
+    if (FAILED(hr = vkd3d_init_depth_stencil_formats(device)))
         goto out_stop_fence_worker;
 
+    if (FAILED(hr = vkd3d_init_null_resources(&device->null_resources, device)))
+        goto out_cleanup_depth_stencil_formats;
+
     vkd3d_render_pass_cache_init(&device->render_pass_cache);
     vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator);
 
@@ -3101,6 +3105,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
 
     return S_OK;
 
+out_cleanup_depth_stencil_formats:
+    vkd3d_cleanup_depth_stencil_formats(device);
 out_stop_fence_worker:
     vkd3d_fence_worker_stop(&device->fence_worker, device);
 out_free_private_store:
diff --git a/libs/vkd3d/utils.c b/libs/vkd3d/utils.c
index 06a958de179a..ea468b37d37d 100644
--- a/libs/vkd3d/utils.c
+++ b/libs/vkd3d/utils.c
@@ -132,6 +132,53 @@ static const struct vkd3d_format vkd3d_depth_stencil_formats[] =
 #undef STENCIL
 #undef DEPTH_STENCIL
 
+HRESULT vkd3d_init_depth_stencil_formats(struct d3d12_device *device)
+{
+    const unsigned int count = ARRAY_SIZE(vkd3d_depth_stencil_formats);
+    const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+    VkFormatProperties properties;
+    struct vkd3d_format *formats;
+    unsigned int i;
+
+    VK_CALL(vkGetPhysicalDeviceFormatProperties(device->vk_physical_device,
+            VK_FORMAT_D24_UNORM_S8_UINT, &properties));
+
+    if (properties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
+    {
+        device->depth_stencil_formats = vkd3d_depth_stencil_formats;
+    }
+    else
+    {
+        /* AMD doesn't support VK_FORMAT_D24_UNORM_S8_UINT. */
+        WARN("Mapping VK_FORMAT_D24_UNORM_S8_UINT to VK_FORMAT_D32_SFLOAT_S8_UINT.\n");
+
+        if (!(formats = vkd3d_calloc(count, sizeof(*formats))))
+            return E_OUTOFMEMORY;
+
+        memcpy(formats, vkd3d_depth_stencil_formats, sizeof(vkd3d_depth_stencil_formats));
+        for (i = 0; i < count; ++i)
+        {
+            if (formats[i].vk_format == VK_FORMAT_D24_UNORM_S8_UINT)
+            {
+                formats[i].vk_format = VK_FORMAT_D32_SFLOAT_S8_UINT;
+                formats[i].is_emulated = true;
+            }
+        }
+
+        device->depth_stencil_formats = formats;
+    }
+
+    return S_OK;
+}
+
+void vkd3d_cleanup_depth_stencil_formats(struct d3d12_device *device)
+{
+    if (vkd3d_depth_stencil_formats != device->depth_stencil_formats)
+        vkd3d_free((void *)device->depth_stencil_formats);
+
+    device->depth_stencil_formats = NULL;
+}
+
 /* We use overrides for depth/stencil formats. This is required in order to
  * properly support typeless formats because depth/stencil formats are only
  * compatible with themselves in Vulkan.
@@ -139,14 +186,16 @@ static const struct vkd3d_format vkd3d_depth_stencil_formats[] =
 static const struct vkd3d_format *vkd3d_get_depth_stencil_format(const struct d3d12_device *device,
         DXGI_FORMAT dxgi_format)
 {
+    const struct vkd3d_format *formats;
     unsigned int i;
 
     assert(device);
+    formats = device->depth_stencil_formats;
 
     for (i = 0; i < ARRAY_SIZE(vkd3d_depth_stencil_formats); ++i)
     {
-        if (vkd3d_depth_stencil_formats[i].dxgi_format == dxgi_format)
-            return &vkd3d_depth_stencil_formats[i];
+        if (formats[i].dxgi_format == dxgi_format)
+            return &formats[i];
     }
 
     return NULL;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 915f63475330..057a0a7c0dea 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1006,6 +1006,7 @@ struct d3d12_device
 
     HRESULT removed_reason;
 
+    const struct vkd3d_format *depth_stencil_formats;
     struct vkd3d_null_resources null_resources;
 };
 
@@ -1027,6 +1028,7 @@ struct vkd3d_format
     size_t block_height;
     size_t block_byte_count;
     VkImageAspectFlags vk_aspect_mask;
+    bool is_emulated;
 };
 
 static inline bool vkd3d_format_is_compressed(const struct vkd3d_format *format)
@@ -1037,6 +1039,9 @@ static inline bool vkd3d_format_is_compressed(const struct vkd3d_format *format)
 const struct vkd3d_format *vkd3d_get_format(const struct d3d12_device *device,
         DXGI_FORMAT dxgi_format, bool depth_stencil) DECLSPEC_HIDDEN;
 
+HRESULT vkd3d_init_depth_stencil_formats(struct d3d12_device *device) DECLSPEC_HIDDEN;
+void vkd3d_cleanup_depth_stencil_formats(struct d3d12_device *device) DECLSPEC_HIDDEN;
+
 bool dxgi_format_is_typeless(DXGI_FORMAT dxgi_format) DECLSPEC_HIDDEN;
 
 static inline const struct vkd3d_format *vkd3d_format_from_d3d12_resource_desc(
diff --git a/tests/d3d12.c b/tests/d3d12.c
index d5f491e190f1..c1992a81923b 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -17749,13 +17749,6 @@ static void test_depth_stencil_sampling(void)
     {
         vkd3d_test_set_context("Test %u", i);
 
-        /* FIXME: Implement format substitution. */
-        if (tests[i].typeless_format == DXGI_FORMAT_R24G8_TYPELESS && is_radv_device(device))
-        {
-            skip("radv doesn't support VK_FORMAT_D24_UNORM_S8_UINT.\n");
-            continue;
-        }
-
         reset_command_list(command_list, context.allocator);
 
         init_depth_stencil(&ds, device, context.render_target_desc.Width,
-- 
2.21.0




More information about the wine-devel mailing list