From e01eae5b8a1603d2e62272ed94b4d85cd002d350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 7 May 2019 15:37:03 +0200 Subject: [PATCH] vkd3d: Use D32_SFLOAT_S8_UINT when D24_UNORM_S8_UINT is not supported. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes rendering in UE4 Infiltrator Demo on AMD. Adjustments for depth bias aren't implemented yet. Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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 57415deb..abe4f27e 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 f1ad0903..a107e1e6 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 06a958de..ea468b37 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 915f6347..057a0a7c 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 d5f491e1..c1992a81 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,