From 757be61b700c56c49f7ba32545a3b1f464e2d2bd Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sun, 6 May 2018 13:12:30 +0200 Subject: [PATCH] [dxgi] Use per-adapter format lookup tables Allows Nvidia cards to use 24-bit depth buffers. --- src/dxgi/dxgi_adapter.cpp | 5 ++-- src/dxgi/dxgi_adapter.h | 10 +++---- src/dxgi/dxgi_format.cpp | 63 +++++++++++++++++++++++++++++---------- src/dxgi/dxgi_format.h | 47 ++++++++++++++++++++++++----- 4 files changed, 94 insertions(+), 31 deletions(-) diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index f38e3604..a562133f 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -18,7 +18,8 @@ namespace dxvk { DxgiFactory* factory, const Rc& adapter) : m_factory (factory), - m_adapter (adapter) { + m_adapter (adapter), + m_formats (adapter) { } @@ -191,7 +192,7 @@ namespace dxvk { DXGI_VK_FORMAT_INFO STDMETHODCALLTYPE DxgiAdapter::LookupFormat( DXGI_FORMAT Format, DXGI_VK_FORMAT_MODE Mode) { - return GetDXGIFormatInfo(Format, Mode); + return m_formats.GetFormatInfo(Format, Mode); } diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h index 0976544a..3bdd0bcb 100644 --- a/src/dxgi/dxgi_adapter.h +++ b/src/dxgi/dxgi_adapter.h @@ -1,13 +1,9 @@ #pragma once -#include -#include +#include #include -#include -#include - -#include +#include "dxgi_format.h" #include "dxgi_interfaces.h" #include "dxgi_output.h" @@ -77,6 +73,8 @@ namespace dxvk { Com m_factory; Rc m_adapter; + DXGIVkFormatTable m_formats; + std::mutex m_outputMutex; OutputMap m_outputData; diff --git a/src/dxgi/dxgi_format.cpp b/src/dxgi/dxgi_format.cpp index b18e1ce1..6c01da25 100644 --- a/src/dxgi/dxgi_format.cpp +++ b/src/dxgi/dxgi_format.cpp @@ -216,21 +216,21 @@ namespace dxvk { VK_IMAGE_ASPECT_COLOR_BIT }, // DXGI_FORMAT_R24G8_TYPELESS { VK_FORMAT_UNDEFINED, - VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED }, // DXGI_FORMAT_D24_UNORM_S8_UINT { VK_FORMAT_UNDEFINED, - VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED, 0, VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT }, // DXGI_FORMAT_R24_UNORM_X8_TYPELESS { VK_FORMAT_UNDEFINED, - VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED, 0, VK_IMAGE_ASPECT_DEPTH_BIT }, // DXGI_FORMAT_X24_TYPELESS_G8_UINT { VK_FORMAT_UNDEFINED, - VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED, 0, VK_IMAGE_ASPECT_STENCIL_BIT }, // DXGI_FORMAT_R8G8_TYPELESS @@ -533,21 +533,36 @@ namespace dxvk { }}; - const DXGI_VK_FORMAT_MAPPING& GetDXGIFormatMapping( - DXGI_FORMAT Format) { - const size_t formatId = size_t(Format); - - return formatId < g_dxgiFormats.size() - ? g_dxgiFormats[formatId] - : g_dxgiFormats[0]; + DXGIVkFormatTable::DXGIVkFormatTable(const Rc& adapter) + : m_dxgiFormats(g_dxgiFormats) { + // AMD do not support 24-bit depth buffers on Vulkan, + // so we have to fall back to a 32-bit depth format. + if (!CheckImageFormatSupport(adapter, VK_FORMAT_D24_UNORM_S8_UINT, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | + VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { + Logger::warn("DXGI: VK_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT"); + RemapDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); + RemapDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); + RemapDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + RemapDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + } } - DXGI_VK_FORMAT_INFO GetDXGIFormatInfo( + DXGIVkFormatTable::~DXGIVkFormatTable() { + + } + + + DXGI_VK_FORMAT_INFO DXGIVkFormatTable::GetFormatInfo( DXGI_FORMAT Format, - DXGI_VK_FORMAT_MODE Mode) { + DXGI_VK_FORMAT_MODE Mode) const { + const size_t formatId = size_t(Format); + const DXGI_VK_FORMAT_MAPPING& mapping - = GetDXGIFormatMapping(Format); + = formatId < m_dxgiFormats.size() + ? m_dxgiFormats[formatId] + : m_dxgiFormats[0]; switch (Mode) { case DXGI_VK_FORMAT_MODE_ANY: @@ -565,8 +580,26 @@ namespace dxvk { return { mapping.FormatRaw, mapping.AspectColor }; } - Logger::err("DXGI: GetDXGIFormatInfo: Internal error"); + Logger::err("DXGI: GetFormatInfo: Internal error"); return DXGI_VK_FORMAT_INFO(); } + + bool DXGIVkFormatTable::CheckImageFormatSupport( + const Rc& Adapter, + VkFormat Format, + VkFormatFeatureFlags Features) const { + VkFormatProperties supported = Adapter->formatProperties(VK_FORMAT_D24_UNORM_S8_UINT); + + return (supported.linearTilingFeatures & Features) == Features + || (supported.optimalTilingFeatures & Features) == Features; + } + + + void DXGIVkFormatTable::RemapDepthFormat( + DXGI_FORMAT Format, + VkFormat Target) { + m_dxgiFormats[uint32_t(Format)].FormatDepth = Target; + } + } \ No newline at end of file diff --git a/src/dxgi/dxgi_format.h b/src/dxgi/dxgi_format.h index 86e6ee6b..0e96cf35 100644 --- a/src/dxgi/dxgi_format.h +++ b/src/dxgi/dxgi_format.h @@ -2,7 +2,7 @@ #include "dxgi_include.h" -#include "../dxvk/dxvk_include.h" +#include "../dxvk/dxvk_adapter.h" namespace dxvk { @@ -53,15 +53,46 @@ namespace dxvk { DXGI_VK_FORMAT_MODE_RAW = 3, ///< Unsigned integer format }; + /** - * \brief Retrieves info for a given DXGI format + * \brief Format table * - * \param [in] Format The DXGI format to look up - * \param [in] Mode the format lookup mode - * \returns Format info + * Initializes a format table for a specific + * device and provides methods to look up + * formats. */ - DXGI_VK_FORMAT_INFO GetDXGIFormatInfo( - DXGI_FORMAT Format, - DXGI_VK_FORMAT_MODE Mode); + class DXGIVkFormatTable { + + public: + + DXGIVkFormatTable( + const Rc& adapter); + ~DXGIVkFormatTable(); + + /** + * \brief Retrieves info for a given DXGI format + * + * \param [in] Format The DXGI format to look up + * \param [in] Mode the format lookup mode + * \returns Format info + */ + DXGI_VK_FORMAT_INFO GetFormatInfo( + DXGI_FORMAT Format, + DXGI_VK_FORMAT_MODE Mode) const; + + private: + + std::array m_dxgiFormats; + + bool CheckImageFormatSupport( + const Rc& Adapter, + VkFormat Format, + VkFormatFeatureFlags Features) const; + + void RemapDepthFormat( + DXGI_FORMAT Format, + VkFormat Target); + + }; }; \ No newline at end of file