From 9370929ac16b4f65d35b044fae00b467ce9254c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Fri, 25 Jan 2019 13:23:32 +0100 Subject: [PATCH] vkd3d: Implement D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- include/vkd3d_d3d12.idl | 14 +++++++ libs/vkd3d/device.c | 75 ++++++++++++++++++++++++++++++++++++++ libs/vkd3d/resource.c | 18 +++++++-- libs/vkd3d/vkd3d_private.h | 1 + 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 754bba38..8b2e70fd 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -269,6 +269,20 @@ typedef struct D3D12_FEATURE_DATA_FORMAT_SUPPORT D3D12_FORMAT_SUPPORT2 Support2; } D3D12_FEATURE_DATA_FORMAT_SUPPORT; +typedef enum D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS +{ + D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE = 0x00000000, + D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_TILED_RESOURCE = 0x00000001, +} D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS; + +typedef struct D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS +{ + DXGI_FORMAT Format; + UINT SampleCount; + D3D12_MULTISAMPLE_QUALITY_LEVEL_FLAGS Flags; + UINT NumQualityLevels; +} D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS; + typedef enum D3D12_HEAP_TYPE { D3D12_HEAP_TYPE_DEFAULT = 1, diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 709c61fd..64c8391b 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -1687,6 +1687,68 @@ static void vkd3d_restrict_format_support_for_feature_level(D3D12_FEATURE_DATA_F } } +static HRESULT d3d12_device_check_multisample_quality_levels(struct d3d12_device *device, + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS *data) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkImageFormatProperties vk_properties; + const struct vkd3d_format *format; + VkSampleCountFlagBits vk_samples; + VkImageUsageFlags vk_usage = 0; + VkResult vr; + + TRACE("Format %#x, sample count %u, flags %#x.\n", data->Format, data->SampleCount, data->Flags); + + data->NumQualityLevels = 0; + + if (!(vk_samples = vk_samples_from_sample_count(data->SampleCount))) + WARN("Invalid sample count %u.\n", data->SampleCount); + if (!data->SampleCount) + return E_FAIL; + + if (data->SampleCount == 1) + { + data->NumQualityLevels = 1; + goto done; + } + + if (data->Format == DXGI_FORMAT_UNKNOWN) + goto done; + + if (!(format = vkd3d_get_format(data->Format, false))) + { + FIXME("Unhandled format %#x.\n", data->Format); + return E_INVALIDARG; + } + if (data->Flags) + FIXME("Ignoring flags %#x.\n", data->Flags); + + if (format->vk_aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT) + vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + else + vk_usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + vr = VK_CALL(vkGetPhysicalDeviceImageFormatProperties(device->vk_physical_device, + format->vk_format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, vk_usage, 0, &vk_properties)); + if (vr == VK_ERROR_FORMAT_NOT_SUPPORTED) + { + WARN("Format %#x is not supported.\n", format->dxgi_format); + goto done; + } + if (vr < 0) + { + ERR("Failed to get image format properties, vr %d.\n", vr); + return hresult_from_vk_result(vr); + } + + if (vk_properties.sampleCounts & vk_samples) + data->NumQualityLevels = 1; + +done: + TRACE("Returning %u quality levels.\n", data->NumQualityLevels); + return S_OK; +} + static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *iface, D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) { @@ -1840,6 +1902,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * return S_OK; } + case D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS: + { + D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS *data = feature_data; + + if (feature_data_size != sizeof(*data)) + { + WARN("Invalid size %u.\n", feature_data_size); + return E_INVALIDARG; + } + + return d3d12_device_check_multisample_quality_levels(device, data); + } + case D3D12_FEATURE_GPU_VIRTUAL_ADDRESS_SUPPORT: { D3D12_FEATURE_DATA_GPU_VIRTUAL_ADDRESS_SUPPORT *data = feature_data; diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 016d0509..75a5201b 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -437,9 +437,9 @@ static VkImageType vk_image_type_from_d3d12_resource_dimension(D3D12_RESOURCE_DI } } -VkSampleCountFlagBits vk_samples_from_dxgi_sample_desc(const DXGI_SAMPLE_DESC *desc) +VkSampleCountFlagBits vk_samples_from_sample_count(unsigned int sample_count) { - switch (desc->Count) + switch (sample_count) { case 1: return VK_SAMPLE_COUNT_1_BIT; @@ -456,11 +456,21 @@ VkSampleCountFlagBits vk_samples_from_dxgi_sample_desc(const DXGI_SAMPLE_DESC *d case 64: return VK_SAMPLE_COUNT_64_BIT; default: - FIXME("Unhandled sample count %u.\n", desc->Count); - return VK_SAMPLE_COUNT_1_BIT; + return 0; } } +VkSampleCountFlagBits vk_samples_from_dxgi_sample_desc(const DXGI_SAMPLE_DESC *desc) +{ + VkSampleCountFlagBits vk_samples; + + if ((vk_samples = vk_samples_from_sample_count(desc->Count))) + return vk_samples; + + FIXME("Unhandled sample count %u.\n", desc->Count); + return VK_SAMPLE_COUNT_1_BIT; +} + HRESULT vkd3d_create_buffer(struct d3d12_device *device, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 6b35dc0f..73825bb2 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -974,6 +974,7 @@ static inline unsigned int d3d12_resource_desc_get_sub_resource_count(const D3D1 VkCompareOp vk_compare_op_from_d3d12(D3D12_COMPARISON_FUNC op) DECLSPEC_HIDDEN; VkSampleCountFlagBits vk_samples_from_dxgi_sample_desc(const DXGI_SAMPLE_DESC *desc) DECLSPEC_HIDDEN; +VkSampleCountFlagBits vk_samples_from_sample_count(unsigned int sample_count) DECLSPEC_HIDDEN; bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level) DECLSPEC_HIDDEN; bool check_feature_level_support(D3D_FEATURE_LEVEL feature_level) DECLSPEC_HIDDEN;