diff --git a/src/dxgi/dxgi_format.cpp b/src/dxgi/dxgi_format.cpp index 91956b154..e5746ce13 100644 --- a/src/dxgi/dxgi_format.cpp +++ b/src/dxgi/dxgi_format.cpp @@ -4,7 +4,7 @@ namespace dxvk { - std::array g_dxgiFormats = {{ + const std::array g_dxgiFormats = {{ // DXGI_FORMAT_UNKNOWN { }, // DXGI_FORMAT_R32G32B32A32_TYPELESS @@ -531,10 +531,304 @@ namespace dxvk { // DXGI_FORMAT_V408 { }, // Unsupported }}; + + + const std::array g_dxgiFamilies = {{ + // DXGI_FORMAT_UNKNOWN + { }, + // DXGI_FORMAT_R32G32B32A32_TYPELESS + { VK_FORMAT_R32G32B32A32_UINT, + VK_FORMAT_R32G32B32A32_SINT, + VK_FORMAT_R32G32B32A32_SFLOAT }, + // DXGI_FORMAT_R32G32B32A32_FLOAT + { }, + // DXGI_FORMAT_R32G32B32A32_UINT + { }, + // DXGI_FORMAT_R32G32B32A32_SINT + { }, + // DXGI_FORMAT_R32G32B32_TYPELESS + { VK_FORMAT_R32G32B32_UINT, + VK_FORMAT_R32G32B32_SINT, + VK_FORMAT_R32G32B32_SFLOAT }, + // DXGI_FORMAT_R32G32B32_FLOAT + { }, + // DXGI_FORMAT_R32G32B32_UINT + { }, + // DXGI_FORMAT_R32G32B32_SINT + { }, + // DXGI_FORMAT_R16G16B16A16_TYPELESS + { VK_FORMAT_R16G16B16A16_UNORM, + VK_FORMAT_R16G16B16A16_SNORM, + VK_FORMAT_R16G16B16A16_UINT, + VK_FORMAT_R16G16B16A16_SINT, + VK_FORMAT_R16G16B16A16_SFLOAT }, + // DXGI_FORMAT_R16G16B16A16_FLOAT + { }, + // DXGI_FORMAT_R16G16B16A16_UNORM + { }, + // DXGI_FORMAT_R16G16B16A16_UINT + { }, + // DXGI_FORMAT_R16G16B16A16_SNORM + { }, + // DXGI_FORMAT_R16G16B16A16_SINT + { }, + // DXGI_FORMAT_R32G32_TYPELESS + { VK_FORMAT_R32G32_UINT, + VK_FORMAT_R32G32_SINT, + VK_FORMAT_R32G32_SFLOAT }, + // DXGI_FORMAT_R32G32_FLOAT + { }, + // DXGI_FORMAT_R32G32_UINT + { }, + // DXGI_FORMAT_R32G32_SINT + { }, + // DXGI_FORMAT_R32G8X24_TYPELESS + { }, + // DXGI_FORMAT_D32_FLOAT_S8X24_UINT + { }, + // DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS + { }, + // DXGI_FORMAT_X32_TYPELESS_G8X24_UINT + { }, + // DXGI_FORMAT_R10G10B10A2_TYPELESS + { VK_FORMAT_A2B10G10R10_UNORM_PACK32, + VK_FORMAT_A2B10G10R10_UINT_PACK32 }, + // DXGI_FORMAT_R10G10B10A2_UNORM + { }, + // DXGI_FORMAT_R10G10B10A2_UINT + { }, + // DXGI_FORMAT_R11G11B10_FLOAT + { }, + // DXGI_FORMAT_R8G8B8A8_TYPELESS + { VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_SNORM, + VK_FORMAT_R8G8B8A8_SRGB, + VK_FORMAT_R8G8B8A8_UINT, + VK_FORMAT_R8G8B8A8_SINT }, + // DXGI_FORMAT_R8G8B8A8_UNORM + { VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_SRGB }, + // DXGI_FORMAT_R8G8B8A8_UNORM_SRGB + { VK_FORMAT_R8G8B8A8_UNORM, + VK_FORMAT_R8G8B8A8_SRGB }, + // DXGI_FORMAT_R8G8B8A8_UINT + { }, + // DXGI_FORMAT_R8G8B8A8_SNORM + { }, + // DXGI_FORMAT_R8G8B8A8_SINT + { }, + // DXGI_FORMAT_R16G16_TYPELESS + { VK_FORMAT_R16G16_UNORM, + VK_FORMAT_R16G16_SNORM, + VK_FORMAT_R16G16_UINT, + VK_FORMAT_R16G16_SINT, + VK_FORMAT_R16G16_SFLOAT }, + // DXGI_FORMAT_R16G16_FLOAT + { }, + // DXGI_FORMAT_R16G16_UNORM + { }, + // DXGI_FORMAT_R16G16_UINT + { }, + // DXGI_FORMAT_R16G16_SNORM + { }, + // DXGI_FORMAT_R16G16_SINT + { }, + // DXGI_FORMAT_R32_TYPELESS + { VK_FORMAT_R32_UINT, + VK_FORMAT_R32_SINT, + VK_FORMAT_R32_SFLOAT }, + // DXGI_FORMAT_D32_FLOAT + { }, + // DXGI_FORMAT_R32_FLOAT + { }, + // DXGI_FORMAT_R32_UINT + { }, + // DXGI_FORMAT_R32_SINT + { }, + // DXGI_FORMAT_R24G8_TYPELESS + { }, + // DXGI_FORMAT_D24_UNORM_S8_UINT + { }, + // DXGI_FORMAT_R24_UNORM_X8_TYPELESS + { }, + // DXGI_FORMAT_X24_TYPELESS_G8_UINT + { }, + // DXGI_FORMAT_R8G8_TYPELESS + { VK_FORMAT_R8G8_UNORM, + VK_FORMAT_R8G8_SNORM, + VK_FORMAT_R8G8_UINT, + VK_FORMAT_R8G8_SINT }, + // DXGI_FORMAT_R8G8_UNORM + { }, + // DXGI_FORMAT_R8G8_UINT + { }, + // DXGI_FORMAT_R8G8_SNORM + { }, + // DXGI_FORMAT_R8G8_SINT + { }, + // DXGI_FORMAT_R16_TYPELESS + { VK_FORMAT_R16_UNORM, + VK_FORMAT_R16_SNORM, + VK_FORMAT_R16_UINT, + VK_FORMAT_R16_SINT, + VK_FORMAT_R16_SFLOAT }, + // DXGI_FORMAT_R16_FLOAT + { }, + // DXGI_FORMAT_D16_UNORM + { }, + // DXGI_FORMAT_R16_UNORM + { }, + // DXGI_FORMAT_R16_UINT + { }, + // DXGI_FORMAT_R16_SNORM + { }, + // DXGI_FORMAT_R16_SINT + { }, + // DXGI_FORMAT_R8_TYPELESS + { VK_FORMAT_R8_UNORM, + VK_FORMAT_R8_SNORM, + VK_FORMAT_R8_UINT, + VK_FORMAT_R8_SINT }, + // DXGI_FORMAT_R8_UNORM + { }, + // DXGI_FORMAT_R8_UINT + { }, + // DXGI_FORMAT_R8_SNORM + { }, + // DXGI_FORMAT_R8_SINT + { }, + // DXGI_FORMAT_A8_UNORM + { }, + // DXGI_FORMAT_R1_UNORM + { }, // Unsupported + // DXGI_FORMAT_R9G9B9E5_SHAREDEXP + { }, + // DXGI_FORMAT_R8G8_B8G8_UNORM + { }, + // DXGI_FORMAT_G8R8_G8B8_UNORM + { }, + // DXGI_FORMAT_BC1_TYPELESS + { VK_FORMAT_BC1_RGBA_UNORM_BLOCK, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK }, + // DXGI_FORMAT_BC1_UNORM + { VK_FORMAT_BC1_RGBA_UNORM_BLOCK, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK }, + // DXGI_FORMAT_BC1_UNORM_SRGB + { VK_FORMAT_BC1_RGBA_UNORM_BLOCK, + VK_FORMAT_BC1_RGBA_SRGB_BLOCK }, + // DXGI_FORMAT_BC2_TYPELESS + { VK_FORMAT_BC2_UNORM_BLOCK, + VK_FORMAT_BC2_SRGB_BLOCK }, + // DXGI_FORMAT_BC2_UNORM + { VK_FORMAT_BC2_UNORM_BLOCK, + VK_FORMAT_BC2_SRGB_BLOCK }, + // DXGI_FORMAT_BC2_UNORM_SRGB + { VK_FORMAT_BC2_UNORM_BLOCK, + VK_FORMAT_BC2_SRGB_BLOCK }, + // DXGI_FORMAT_BC3_TYPELESS + { VK_FORMAT_BC3_UNORM_BLOCK, + VK_FORMAT_BC3_SRGB_BLOCK }, + // DXGI_FORMAT_BC3_UNORM + { VK_FORMAT_BC3_UNORM_BLOCK, + VK_FORMAT_BC3_SRGB_BLOCK }, + // DXGI_FORMAT_BC3_UNORM_SRGB + { VK_FORMAT_BC3_UNORM_BLOCK, + VK_FORMAT_BC3_SRGB_BLOCK }, + // DXGI_FORMAT_BC4_TYPELESS + { VK_FORMAT_BC4_UNORM_BLOCK, + VK_FORMAT_BC4_SNORM_BLOCK }, + // DXGI_FORMAT_BC4_UNORM + { }, + // DXGI_FORMAT_BC4_SNORM + { }, + // DXGI_FORMAT_BC5_TYPELESS + { VK_FORMAT_BC5_UNORM_BLOCK, + VK_FORMAT_BC5_SNORM_BLOCK }, + // DXGI_FORMAT_BC5_UNORM + { }, + // DXGI_FORMAT_BC5_SNORM + { }, + // DXGI_FORMAT_B5G6R5_UNORM + { }, + // DXGI_FORMAT_B5G5R5A1_UNORM + { }, + // DXGI_FORMAT_B8G8R8A8_UNORM + { }, + // DXGI_FORMAT_B8G8R8X8_UNORM + { }, + // DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM + { }, // Unsupported + // DXGI_FORMAT_B8G8R8A8_TYPELESS + { VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB }, + // DXGI_FORMAT_B8G8R8A8_UNORM_SRGB + { VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB }, + // DXGI_FORMAT_B8G8R8X8_TYPELESS + { VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB }, + // DXGI_FORMAT_B8G8R8X8_UNORM_SRGB + { VK_FORMAT_B8G8R8A8_UNORM, + VK_FORMAT_B8G8R8A8_SRGB }, + // DXGI_FORMAT_BC6H_TYPELESS + { VK_FORMAT_BC6H_UFLOAT_BLOCK, + VK_FORMAT_BC6H_SFLOAT_BLOCK }, + // DXGI_FORMAT_BC6H_UF16 + { }, + // DXGI_FORMAT_BC6H_SF16 + { }, + // DXGI_FORMAT_BC7_TYPELESS + { VK_FORMAT_BC7_UNORM_BLOCK, + VK_FORMAT_BC7_SRGB_BLOCK }, + // DXGI_FORMAT_BC7_UNORM + { VK_FORMAT_BC7_UNORM_BLOCK, + VK_FORMAT_BC7_SRGB_BLOCK }, + // DXGI_FORMAT_BC7_UNORM_SRGB + { VK_FORMAT_BC7_UNORM_BLOCK, + VK_FORMAT_BC7_SRGB_BLOCK }, + // DXGI_FORMAT_AYUV + { }, // Unsupported + // DXGI_FORMAT_Y410 + { }, // Unsupported + // DXGI_FORMAT_Y416 + { }, // Unsupported + // DXGI_FORMAT_NV12 + { }, // Unsupported + // DXGI_FORMAT_P010 + { }, // Unsupported + // DXGI_FORMAT_P016 + { }, // Unsupported + // DXGI_FORMAT_420_OPAQUE + { }, // Unsupported + // DXGI_FORMAT_YUY2 + { }, // Unsupported + // DXGI_FORMAT_Y210 + { }, // Unsupported + // DXGI_FORMAT_Y216 + { }, // Unsupported + // DXGI_FORMAT_NV11 + { }, // Unsupported + // DXGI_FORMAT_AI44 + { }, // Unsupported + // DXGI_FORMAT_IA44 + { }, // Unsupported + // DXGI_FORMAT_P8 + { }, // Unsupported + // DXGI_FORMAT_A8P8 + { }, // Unsupported + // DXGI_FORMAT_B4G4R4A4_UNORM + { }, // Unsupported + // DXGI_FORMAT_P208 + { }, // Unsupported + // DXGI_FORMAT_V208 + { }, // Unsupported + // DXGI_FORMAT_V408 + { }, // Unsupported + }}; DXGIVkFormatTable::DXGIVkFormatTable(const Rc& adapter) - : m_dxgiFormats(g_dxgiFormats) { + : m_dxgiFormats (g_dxgiFormats), m_dxgiFamilies(g_dxgiFamilies) { // 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, @@ -557,27 +851,22 @@ namespace dxvk { DXGI_VK_FORMAT_INFO DXGIVkFormatTable::GetFormatInfo( DXGI_FORMAT Format, DXGI_VK_FORMAT_MODE Mode) const { - const size_t formatId = size_t(Format); - - const DXGI_VK_FORMAT_MAPPING& mapping - = formatId < m_dxgiFormats.size() - ? m_dxgiFormats[formatId] - : m_dxgiFormats[0]; + const DXGI_VK_FORMAT_MAPPING* mapping = GetFormatMapping(Format); switch (Mode) { case DXGI_VK_FORMAT_MODE_ANY: - return mapping.FormatColor != VK_FORMAT_UNDEFINED - ? DXGI_VK_FORMAT_INFO { mapping.FormatColor, mapping.AspectColor, mapping.Swizzle } - : DXGI_VK_FORMAT_INFO { mapping.FormatDepth, mapping.AspectDepth }; + return mapping->FormatColor != VK_FORMAT_UNDEFINED + ? DXGI_VK_FORMAT_INFO { mapping->FormatColor, mapping->AspectColor, mapping->Swizzle } + : DXGI_VK_FORMAT_INFO { mapping->FormatDepth, mapping->AspectDepth }; case DXGI_VK_FORMAT_MODE_COLOR: - return { mapping.FormatColor, mapping.AspectColor, mapping.Swizzle }; + return { mapping->FormatColor, mapping->AspectColor, mapping->Swizzle }; case DXGI_VK_FORMAT_MODE_DEPTH: - return { mapping.FormatDepth, mapping.AspectDepth }; + return { mapping->FormatDepth, mapping->AspectDepth }; case DXGI_VK_FORMAT_MODE_RAW: - return { mapping.FormatRaw, mapping.AspectColor }; + return { mapping->FormatRaw, mapping->AspectColor }; } Logger::err("DXGI: GetFormatInfo: Internal error"); @@ -585,6 +874,30 @@ namespace dxvk { } + DXGI_VK_FORMAT_FAMILY DXGIVkFormatTable::GetFormatFamily( + DXGI_FORMAT Format, + DXGI_VK_FORMAT_MODE Mode) const { + if (Mode == DXGI_VK_FORMAT_MODE_DEPTH) + return DXGI_VK_FORMAT_FAMILY(); + + const size_t formatId = size_t(Format); + + return formatId < m_dxgiFamilies.size() + ? m_dxgiFamilies[formatId] + : m_dxgiFamilies[0]; + } + + + const DXGI_VK_FORMAT_MAPPING* DXGIVkFormatTable::GetFormatMapping( + DXGI_FORMAT Format) const { + const size_t formatId = size_t(Format); + + return formatId < m_dxgiFormats.size() + ? &m_dxgiFormats[formatId] + : &m_dxgiFormats[0]; + } + + bool DXGIVkFormatTable::CheckImageFormatSupport( const Rc& Adapter, VkFormat Format, diff --git a/src/dxgi/dxgi_format.h b/src/dxgi/dxgi_format.h index 0e96cf359..560782944 100644 --- a/src/dxgi/dxgi_format.h +++ b/src/dxgi/dxgi_format.h @@ -3,6 +3,7 @@ #include "dxgi_include.h" #include "../dxvk/dxvk_adapter.h" +#include "../dxvk/dxvk_format.h" namespace dxvk { @@ -54,6 +55,28 @@ namespace dxvk { }; + /** + * \brief Format family + * + * Stores a set of compatible formats. This can + * be used to aggregate formats for the image + * format list extension. + */ + struct DXGI_VK_FORMAT_FAMILY { + constexpr static size_t MaxSize = 8; + + DXGI_VK_FORMAT_FAMILY() { } + DXGI_VK_FORMAT_FAMILY( + const std::initializer_list& FormatList) { + for (VkFormat f : FormatList) + Formats[FormatCount++] = f; + } + + UINT FormatCount = 0; + VkFormat Formats[MaxSize]; + }; + + /** * \brief Format table * @@ -80,10 +103,25 @@ namespace dxvk { DXGI_FORMAT Format, DXGI_VK_FORMAT_MODE Mode) const; + /** + * \brief Retrieves a format family + * + * \param [in] Format The format to query + * \param [in] Mode Image format mode + * \returns Image format family + */ + DXGI_VK_FORMAT_FAMILY GetFormatFamily( + DXGI_FORMAT Format, + DXGI_VK_FORMAT_MODE Mode) const; + private: std::array m_dxgiFormats; + std::array m_dxgiFamilies; + const DXGI_VK_FORMAT_MAPPING* GetFormatMapping( + DXGI_FORMAT Format) const; + bool CheckImageFormatSupport( const Rc& Adapter, VkFormat Format,