From f2587ab1b6eb55e5ce488421e1ed1f9b1052762b Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Tue, 19 Dec 2017 14:47:35 +0100 Subject: [PATCH] [dxgi] Implemented separate color/depth format tables This is required because in D3D11, typeless formats can be used to create both depth and stencil images, and color formats can be used to view depth images. In Vulkan, images and views that are used as depth-stencil attachments will have to be created with a depth-stencil format, so we have to take the image's bind flags into account when picking a format. --- src/d3d11/d3d11_device.cpp | 34 ++++- src/d3d11/d3d11_present.cpp | 2 +- src/d3d11/d3d11_texture.cpp | 13 +- src/d3d11/d3d11_texture.h | 10 +- src/dxgi/dxgi_adapter.cpp | 290 ++++++++++++++++++------------------ src/dxgi/dxgi_adapter.h | 15 +- src/dxgi/dxgi_interfaces.h | 28 +++- src/dxgi/dxgi_presenter.cpp | 4 +- src/dxgi/dxgi_swapchain.cpp | 2 +- 9 files changed, 221 insertions(+), 177 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index a73fcdf42..c9ef3219a 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -107,9 +107,17 @@ namespace dxvk { const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture2D** ppTexture2D) { + DxgiFormatMode formatMode = DxgiFormatMode::Any; + + if (pDesc->BindFlags & D3D11_BIND_RENDER_TARGET) + formatMode = DxgiFormatMode::Color; + + if (pDesc->BindFlags & D3D11_BIND_DEPTH_STENCIL) + formatMode = DxgiFormatMode::Depth; + DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_2D; - info.format = m_dxgiAdapter->LookupFormat(pDesc->Format).actual; + info.format = m_dxgiAdapter->LookupFormat(pDesc->Format, formatMode).actual; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; info.sampleCount = VK_SAMPLE_COUNT_1_BIT; info.extent.width = pDesc->Width; @@ -187,7 +195,7 @@ namespace dxvk { return hr; *ppTexture2D = ref(new D3D11Texture2D( - this, image.ptr(), *pDesc)); + this, image.ptr(), formatMode, *pDesc)); InitTexture(image.ptr(), pInitialData); } @@ -235,11 +243,20 @@ namespace dxvk { reinterpret_cast(&imageResource)))) return E_INVALIDARG; + // TODO fix this properly + DxgiFormatMode formatMode = DxgiFormatMode::Any; + + Com texture2D; + if (SUCCEEDED(pResource->QueryInterface( + __uuidof(ID3D11Texture2D), + reinterpret_cast(&texture2D)))) + formatMode = texture2D->GetFormatMode(); + // Fill in the view info. The view type depends solely // on the view dimension field in the view description, // not on the resource type. DxvkImageViewCreateInfo viewInfo; - viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; + viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, formatMode).actual; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; switch (desc.ViewDimension) { @@ -383,7 +400,7 @@ namespace dxvk { // Fill in Vulkan image view info DxvkImageViewCreateInfo viewInfo; - viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; + viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Color).actual; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; switch (desc.ViewDimension) { @@ -478,7 +495,7 @@ namespace dxvk { // Fill in Vulkan image view info DxvkImageViewCreateInfo viewInfo; - viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format).actual; + viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Depth).actual; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; switch (desc.ViewDimension) { @@ -573,7 +590,7 @@ namespace dxvk { attrib.location = entry->registerId; attrib.binding = pInputElementDescs[i].InputSlot; attrib.format = m_dxgiAdapter->LookupFormat( - pInputElementDescs[i].Format).actual; + pInputElementDescs[i].Format, DxgiFormatMode::Color).actual; attrib.offset = pInputElementDescs[i].AlignedByteOffset; // The application may choose to let the implementation @@ -964,7 +981,8 @@ namespace dxvk { *pNumQualityLevels = 0; // We need to check whether the format is - VkFormat format = m_dxgiAdapter->LookupFormat(Format).actual; + VkFormat format = m_dxgiAdapter->LookupFormat( + Format, DxgiFormatMode::Any).actual; if (format == VK_FORMAT_UNDEFINED) { Logger::err(str::format("D3D11: Unsupported format: ", Format)); @@ -1466,7 +1484,7 @@ namespace dxvk { HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const { - const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format).actual; + const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).actual; const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt); if (fmt == VK_FORMAT_UNDEFINED) diff --git a/src/d3d11/d3d11_present.cpp b/src/d3d11/d3d11_present.cpp index 81bba6fb5..a090a9cfb 100644 --- a/src/d3d11/d3d11_present.cpp +++ b/src/d3d11/d3d11_present.cpp @@ -35,7 +35,7 @@ namespace dxvk { desc.MiscFlags = 0; *ppInterface = ref(new D3D11Texture2D( - m_device, pResource, desc)); + m_device, pResource, DxgiFormatMode::Color, desc)); return S_OK; } diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 59a9c669b..d7d594c66 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -6,10 +6,12 @@ namespace dxvk { D3D11Texture2D::D3D11Texture2D( D3D11Device* device, IDXGIImageResourcePrivate* resource, + DxgiFormatMode formatMode, const D3D11_TEXTURE2D_DESC& desc) - : m_device (device), - m_resource(resource), - m_desc (desc) { + : m_device (device), + m_resource (resource), + m_formatMode(formatMode), + m_desc (desc) { } @@ -60,9 +62,4 @@ namespace dxvk { *pDesc = m_desc; } - - Rc D3D11Texture2D::GetDXVKImage() { - return m_resource->GetDXVKImage(); - } - } diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 9f5b35144..1e2dddd5a 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -17,6 +17,7 @@ namespace dxvk { D3D11Texture2D( D3D11Device* device, IDXGIImageResourcePrivate* resource, + DxgiFormatMode formatMode, const D3D11_TEXTURE2D_DESC& desc); ~D3D11Texture2D(); @@ -37,12 +38,19 @@ namespace dxvk { void STDMETHODCALLTYPE GetDesc( D3D11_TEXTURE2D_DESC *pDesc) final; - Rc GetDXVKImage(); + DxgiFormatMode GetFormatMode() const { + return m_formatMode; + } + + Rc GetDXVKImage() const { + return m_resource->GetDXVKImage(); + } private: Com m_device; Com m_resource; + DxgiFormatMode m_formatMode; D3D11_TEXTURE2D_DESC m_desc; }; diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 64fa10ec3..f317b1f7b 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -138,200 +138,194 @@ namespace dxvk { } - DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format) { - auto pair = m_formats.find(format); + DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format, DxgiFormatMode mode) { + // If the mode is 'Any', probe color formats first + if (mode != DxgiFormatMode::Depth) { + auto color = m_colorFormats.find(format); + + if (color != m_colorFormats.end()) + return color->second; + } - return pair != m_formats.end() - ? pair->second - : DxgiFormatPair(); + if (mode != DxgiFormatMode::Color) { + auto depth = m_depthFormats.find(format); + if (depth != m_depthFormats.end()) + return depth->second; + } + + return DxgiFormatPair(); } - void DxgiAdapter::AddFormat( + void DxgiAdapter::AddColorFormat( DXGI_FORMAT srcFormat, VkFormat dstFormat) { DxgiFormatPair formatPair; formatPair.wanted = dstFormat; formatPair.actual = dstFormat; - m_formats.insert(std::make_pair(srcFormat, formatPair)); + m_colorFormats.insert(std::make_pair(srcFormat, formatPair)); } - void DxgiAdapter::AddFormat( + void DxgiAdapter::AddDepthFormat( DXGI_FORMAT srcFormat, - VkFormat dstFormat, - const std::initializer_list& fallbacks, - VkFormatFeatureFlags features) { + VkFormat dstFormat) { DxgiFormatPair formatPair; formatPair.wanted = dstFormat; - formatPair.actual = VK_FORMAT_UNDEFINED; - - if (this->HasFormatSupport(dstFormat, features)) { - formatPair.actual = dstFormat; - } else { - for (VkFormat fmt : fallbacks) { - if (this->HasFormatSupport(fmt, features)) { - formatPair.actual = fmt; - break; - } - } - } - - if (formatPair.actual == VK_FORMAT_UNDEFINED) - Logger::err(str::format("DxgiAdapter: ", srcFormat, " not supported")); - else if (formatPair.actual != formatPair.wanted) - Logger::warn(str::format("DxgiAdapter: ", srcFormat, " -> ", formatPair.actual)); - - m_formats.insert(std::make_pair(srcFormat, formatPair)); + formatPair.actual = dstFormat; + m_depthFormats.insert(std::make_pair(srcFormat, formatPair)); } void DxgiAdapter::SetupFormatTable() { - AddFormat(DXGI_FORMAT_UNKNOWN, VK_FORMAT_UNDEFINED); + /***********************************************************************************/ + /* C O L O R F O R M A T S */ + AddColorFormat(DXGI_FORMAT_UNKNOWN, VK_FORMAT_UNDEFINED); - AddFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, VK_FORMAT_R32G32B32A32_UINT); - AddFormat(DXGI_FORMAT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT); - AddFormat(DXGI_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT); - AddFormat(DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT); + AddColorFormat(DXGI_FORMAT_R32G32B32A32_TYPELESS, VK_FORMAT_R32G32B32A32_UINT); + AddColorFormat(DXGI_FORMAT_R32G32B32A32_FLOAT, VK_FORMAT_R32G32B32A32_SFLOAT); + AddColorFormat(DXGI_FORMAT_R32G32B32A32_UINT, VK_FORMAT_R32G32B32A32_UINT); + AddColorFormat(DXGI_FORMAT_R32G32B32A32_SINT, VK_FORMAT_R32G32B32A32_SINT); - AddFormat(DXGI_FORMAT_R32G32B32_TYPELESS, VK_FORMAT_R32G32B32_UINT); - AddFormat(DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT); - AddFormat(DXGI_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT); - AddFormat(DXGI_FORMAT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT); + AddColorFormat(DXGI_FORMAT_R32G32B32_TYPELESS, VK_FORMAT_R32G32B32_UINT); + AddColorFormat(DXGI_FORMAT_R32G32B32_FLOAT, VK_FORMAT_R32G32B32_SFLOAT); + AddColorFormat(DXGI_FORMAT_R32G32B32_UINT, VK_FORMAT_R32G32B32_UINT); + AddColorFormat(DXGI_FORMAT_R32G32B32_SINT, VK_FORMAT_R32G32B32_SINT); - AddFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, VK_FORMAT_R16G16B16A16_UINT); - AddFormat(DXGI_FORMAT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT); - AddFormat(DXGI_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM); - AddFormat(DXGI_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT); - AddFormat(DXGI_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM); - AddFormat(DXGI_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT); + AddColorFormat(DXGI_FORMAT_R16G16B16A16_TYPELESS, VK_FORMAT_R16G16B16A16_UINT); + AddColorFormat(DXGI_FORMAT_R16G16B16A16_FLOAT, VK_FORMAT_R16G16B16A16_SFLOAT); + AddColorFormat(DXGI_FORMAT_R16G16B16A16_UNORM, VK_FORMAT_R16G16B16A16_UNORM); + AddColorFormat(DXGI_FORMAT_R16G16B16A16_UINT, VK_FORMAT_R16G16B16A16_UINT); + AddColorFormat(DXGI_FORMAT_R16G16B16A16_SNORM, VK_FORMAT_R16G16B16A16_SNORM); + AddColorFormat(DXGI_FORMAT_R16G16B16A16_SINT, VK_FORMAT_R16G16B16A16_SINT); - AddFormat(DXGI_FORMAT_R32G32_TYPELESS, VK_FORMAT_R32G32_UINT); - AddFormat(DXGI_FORMAT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT); - AddFormat(DXGI_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT); - AddFormat(DXGI_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT); + AddColorFormat(DXGI_FORMAT_R32G32_TYPELESS, VK_FORMAT_R32G32_UINT); + AddColorFormat(DXGI_FORMAT_R32G32_FLOAT, VK_FORMAT_R32G32_SFLOAT); + AddColorFormat(DXGI_FORMAT_R32G32_UINT, VK_FORMAT_R32G32_UINT); + AddColorFormat(DXGI_FORMAT_R32G32_SINT, VK_FORMAT_R32G32_SINT); - AddFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); -// AddFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_UNDEFINED); -// AddFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_UNDEFINED); -// AddFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_UNDEFINED); + AddColorFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS, VK_FORMAT_A2R10G10B10_UINT_PACK32); + AddColorFormat(DXGI_FORMAT_R10G10B10A2_UINT, VK_FORMAT_A2R10G10B10_UINT_PACK32); + AddColorFormat(DXGI_FORMAT_R10G10B10A2_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32); - AddFormat(DXGI_FORMAT_R10G10B10A2_TYPELESS, VK_FORMAT_A2R10G10B10_UINT_PACK32); - AddFormat(DXGI_FORMAT_R10G10B10A2_UINT, VK_FORMAT_A2R10G10B10_UINT_PACK32); - AddFormat(DXGI_FORMAT_R10G10B10A2_UNORM, VK_FORMAT_A2R10G10B10_UNORM_PACK32); + AddColorFormat(DXGI_FORMAT_R11G11B10_FLOAT, VK_FORMAT_B10G11R11_UFLOAT_PACK32); - AddFormat(DXGI_FORMAT_R11G11B10_FLOAT, VK_FORMAT_B10G11R11_UFLOAT_PACK32); + AddColorFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, VK_FORMAT_R8G8B8A8_UINT); + AddColorFormat(DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM); + AddColorFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB); + AddColorFormat(DXGI_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT); + AddColorFormat(DXGI_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM); + AddColorFormat(DXGI_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT); - AddFormat(DXGI_FORMAT_R8G8B8A8_TYPELESS, VK_FORMAT_R8G8B8A8_UINT); - AddFormat(DXGI_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM); - AddFormat(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, VK_FORMAT_R8G8B8A8_SRGB); - AddFormat(DXGI_FORMAT_R8G8B8A8_UINT, VK_FORMAT_R8G8B8A8_UINT); - AddFormat(DXGI_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_R8G8B8A8_SNORM); - AddFormat(DXGI_FORMAT_R8G8B8A8_SINT, VK_FORMAT_R8G8B8A8_SINT); + AddColorFormat(DXGI_FORMAT_R16G16_TYPELESS, VK_FORMAT_R16G16_UINT); + AddColorFormat(DXGI_FORMAT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT); + AddColorFormat(DXGI_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM); + AddColorFormat(DXGI_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT); + AddColorFormat(DXGI_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM); + AddColorFormat(DXGI_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT); - AddFormat(DXGI_FORMAT_R16G16_TYPELESS, VK_FORMAT_R16G16_UINT); - AddFormat(DXGI_FORMAT_R16G16_FLOAT, VK_FORMAT_R16G16_SFLOAT); - AddFormat(DXGI_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16_UNORM); - AddFormat(DXGI_FORMAT_R16G16_UINT, VK_FORMAT_R16G16_UINT); - AddFormat(DXGI_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16_SNORM); - AddFormat(DXGI_FORMAT_R16G16_SINT, VK_FORMAT_R16G16_SINT); + AddColorFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_R32_UINT); + AddColorFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT); + AddColorFormat(DXGI_FORMAT_R32_UINT, VK_FORMAT_R32_UINT); + AddColorFormat(DXGI_FORMAT_R32_SINT, VK_FORMAT_R32_SINT); - AddFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_R32_UINT); - AddFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_R32_SFLOAT); - AddFormat(DXGI_FORMAT_R32_UINT, VK_FORMAT_R32_UINT); - AddFormat(DXGI_FORMAT_R32_SINT, VK_FORMAT_R32_SINT); + AddColorFormat(DXGI_FORMAT_R8G8_TYPELESS, VK_FORMAT_R8G8_UINT); + AddColorFormat(DXGI_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM); + AddColorFormat(DXGI_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT); + AddColorFormat(DXGI_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM); + AddColorFormat(DXGI_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT); - AddFormat(DXGI_FORMAT_R8G8_TYPELESS, VK_FORMAT_R8G8_UINT); - AddFormat(DXGI_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8_UNORM); - AddFormat(DXGI_FORMAT_R8G8_UINT, VK_FORMAT_R8G8_UINT); - AddFormat(DXGI_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8_SNORM); - AddFormat(DXGI_FORMAT_R8G8_SINT, VK_FORMAT_R8G8_SINT); + AddColorFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_R16_UINT); + AddColorFormat(DXGI_FORMAT_R16_FLOAT, VK_FORMAT_R16_SFLOAT); + AddColorFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM); + AddColorFormat(DXGI_FORMAT_R16_UINT, VK_FORMAT_R16_UINT); + AddColorFormat(DXGI_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM); + AddColorFormat(DXGI_FORMAT_R16_SINT, VK_FORMAT_R16_SINT); - AddFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_R16_UINT); - AddFormat(DXGI_FORMAT_R16_FLOAT, VK_FORMAT_R16_SFLOAT); - AddFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_R16_UNORM); - AddFormat(DXGI_FORMAT_R16_UINT, VK_FORMAT_R16_UINT); - AddFormat(DXGI_FORMAT_R16_SNORM, VK_FORMAT_R16_SNORM); - AddFormat(DXGI_FORMAT_R16_SINT, VK_FORMAT_R16_SINT); + AddColorFormat(DXGI_FORMAT_R8_TYPELESS, VK_FORMAT_R8_UINT); + AddColorFormat(DXGI_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM); + AddColorFormat(DXGI_FORMAT_R8_UINT, VK_FORMAT_R8_UINT); + AddColorFormat(DXGI_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM); + AddColorFormat(DXGI_FORMAT_R8_SINT, VK_FORMAT_R8_SINT); - AddFormat(DXGI_FORMAT_R8_TYPELESS, VK_FORMAT_R8_UINT); - AddFormat(DXGI_FORMAT_R8_UNORM, VK_FORMAT_R8_UNORM); - AddFormat(DXGI_FORMAT_R8_UINT, VK_FORMAT_R8_UINT); - AddFormat(DXGI_FORMAT_R8_SNORM, VK_FORMAT_R8_SNORM); - AddFormat(DXGI_FORMAT_R8_SINT, VK_FORMAT_R8_SINT); -// AddFormat(DXGI_FORMAT_A8_UNORM, VK_FORMAT_UNDEFINED); +// AddColorFormat(DXGI_FORMAT_A8_UNORM, VK_FORMAT_UNDEFINED); -// AddFormat(DXGI_FORMAT_R1_UNORM, VK_FORMAT_UNDEFINED); +// AddColorFormat(DXGI_FORMAT_R1_UNORM, VK_FORMAT_UNDEFINED); - AddFormat(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32); -// AddFormat(DXGI_FORMAT_R8G8_B8G8_UNORM, VK_FORMAT_UNDEFINED); - AddFormat(DXGI_FORMAT_G8R8_G8B8_UNORM, VK_FORMAT_UNDEFINED); + AddColorFormat(DXGI_FORMAT_R9G9B9E5_SHAREDEXP, VK_FORMAT_E5B9G9R9_UFLOAT_PACK32); +// AddColorFormat(DXGI_FORMAT_R8G8_B8G8_UNORM, VK_FORMAT_UNDEFINED); +// AddColorFormat(DXGI_FORMAT_G8R8_G8B8_UNORM, VK_FORMAT_UNDEFINED); - AddFormat(DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK); + AddColorFormat(DXGI_FORMAT_B5G6R5_UNORM, VK_FORMAT_B5G6R5_UNORM_PACK16); + AddColorFormat(DXGI_FORMAT_B5G5R5A1_UNORM, VK_FORMAT_B5G5R5A1_UNORM_PACK16); - AddFormat(DXGI_FORMAT_BC2_TYPELESS, VK_FORMAT_BC2_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK); - - AddFormat(DXGI_FORMAT_BC3_TYPELESS, VK_FORMAT_BC3_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC3_UNORM, VK_FORMAT_BC3_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC3_UNORM_SRGB, VK_FORMAT_BC3_SRGB_BLOCK); - - AddFormat(DXGI_FORMAT_BC4_TYPELESS, VK_FORMAT_BC4_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC4_UNORM, VK_FORMAT_BC4_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC4_SNORM, VK_FORMAT_BC4_SNORM_BLOCK); - - AddFormat(DXGI_FORMAT_BC5_TYPELESS, VK_FORMAT_BC5_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC5_UNORM, VK_FORMAT_BC5_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC5_SNORM, VK_FORMAT_BC5_SNORM_BLOCK); - - AddFormat(DXGI_FORMAT_B5G6R5_UNORM, VK_FORMAT_B5G6R5_UNORM_PACK16); - AddFormat(DXGI_FORMAT_B5G5R5A1_UNORM, VK_FORMAT_B5G5R5A1_UNORM_PACK16); - - AddFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM); - AddFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM); - AddFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB); + AddColorFormat(DXGI_FORMAT_B8G8R8A8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM); + AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM); + AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB); // TODO implement component swizzle - AddFormat(DXGI_FORMAT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM); - AddFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM); - AddFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB); + AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM); + AddColorFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM); + AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB); +// AddColorFormat(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, VK_FORMAT_UNDEFINED); -// AddFormat(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, VK_FORMAT_UNDEFINED); + /***********************************************************************************/ + /* B L O C K F O R M A T S */ + AddColorFormat(DXGI_FORMAT_BC1_TYPELESS, VK_FORMAT_BC1_RGBA_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC1_UNORM, VK_FORMAT_BC1_RGBA_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC1_UNORM_SRGB, VK_FORMAT_BC1_RGBA_SRGB_BLOCK); - AddFormat(DXGI_FORMAT_BC6H_TYPELESS, VK_FORMAT_BC6H_UFLOAT_BLOCK); - AddFormat(DXGI_FORMAT_BC6H_UF16, VK_FORMAT_BC6H_UFLOAT_BLOCK); - AddFormat(DXGI_FORMAT_BC6H_SF16, VK_FORMAT_BC6H_SFLOAT_BLOCK); + AddColorFormat(DXGI_FORMAT_BC2_TYPELESS, VK_FORMAT_BC2_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC2_UNORM, VK_FORMAT_BC2_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC2_UNORM_SRGB, VK_FORMAT_BC2_SRGB_BLOCK); - AddFormat(DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK); - AddFormat(DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK); + AddColorFormat(DXGI_FORMAT_BC3_TYPELESS, VK_FORMAT_BC3_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC3_UNORM, VK_FORMAT_BC3_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC3_UNORM_SRGB, VK_FORMAT_BC3_SRGB_BLOCK); - AddFormat( - DXGI_FORMAT_D32_FLOAT, - VK_FORMAT_D32_SFLOAT, { - VK_FORMAT_D32_SFLOAT_S8_UINT, - }, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + AddColorFormat(DXGI_FORMAT_BC4_TYPELESS, VK_FORMAT_BC4_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC4_UNORM, VK_FORMAT_BC4_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC4_SNORM, VK_FORMAT_BC4_SNORM_BLOCK); - AddFormat( - DXGI_FORMAT_D24_UNORM_S8_UINT, - VK_FORMAT_D24_UNORM_S8_UINT, { - VK_FORMAT_D32_SFLOAT_S8_UINT, - }, - VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); + AddColorFormat(DXGI_FORMAT_BC5_TYPELESS, VK_FORMAT_BC5_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC5_UNORM, VK_FORMAT_BC5_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC5_SNORM, VK_FORMAT_BC5_SNORM_BLOCK); - AddFormat(DXGI_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM); + AddColorFormat(DXGI_FORMAT_BC6H_TYPELESS, VK_FORMAT_BC6H_UFLOAT_BLOCK); + AddColorFormat(DXGI_FORMAT_BC6H_UF16, VK_FORMAT_BC6H_UFLOAT_BLOCK); + AddColorFormat(DXGI_FORMAT_BC6H_SF16, VK_FORMAT_BC6H_SFLOAT_BLOCK); -// AddFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_UNDEFINED); -// AddFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_UNDEFINED); -// AddFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_UNDEFINED); + AddColorFormat(DXGI_FORMAT_BC7_TYPELESS, VK_FORMAT_BC7_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC7_UNORM, VK_FORMAT_BC7_UNORM_BLOCK); + AddColorFormat(DXGI_FORMAT_BC7_UNORM_SRGB, VK_FORMAT_BC7_SRGB_BLOCK); - // TODO finish me + /***********************************************************************************/ + /* D E P T H F O R M A T S */ + AddDepthFormat(DXGI_FORMAT_D16_UNORM, VK_FORMAT_D16_UNORM); + AddDepthFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM); + AddDepthFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM); + + AddDepthFormat(DXGI_FORMAT_D32_FLOAT, VK_FORMAT_D32_SFLOAT); + AddDepthFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT); + AddDepthFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT); + + AddDepthFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + AddDepthFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); + AddDepthFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); + AddDepthFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + + // Vulkan implementations are not required to support 24-bit depth buffers natively + // and AMD decided to not implement them, so we'll fall back to 32-bit depth buffers + if (HasFormatSupport(VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { + AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT); + AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT); + AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT); + } else { + Logger::warn("DxgiAdapter: DXGI_FORMAT_D24_UNORM_S8_UINT -> VK_FORMAT_D32_SFLOAT_S8_UINT"); + AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT); + AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT); + } } diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h index 242ad933d..3e5d5ec98 100644 --- a/src/dxgi/dxgi_adapter.h +++ b/src/dxgi/dxgi_adapter.h @@ -49,24 +49,25 @@ namespace dxvk { Rc STDMETHODCALLTYPE GetDXVKAdapter() final; DxgiFormatPair STDMETHODCALLTYPE LookupFormat( - DXGI_FORMAT format) final; + DXGI_FORMAT format, DxgiFormatMode mode) final; private: + using FormatMap = std::unordered_map; + Com m_factory; Rc m_adapter; - std::unordered_map m_formats; + FormatMap m_colorFormats; + FormatMap m_depthFormats; - void AddFormat( + void AddColorFormat( DXGI_FORMAT srcFormat, VkFormat dstFormat); - void AddFormat( + void AddDepthFormat( DXGI_FORMAT srcFormat, - VkFormat dstFormat, - const std::initializer_list& fallbacks, - VkFormatFeatureFlags features); + VkFormat dstFormat); void SetupFormatTable(); diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index 9bdc0d815..5be22fe0d 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -24,6 +24,20 @@ namespace dxvk { VkFormat wanted = VK_FORMAT_UNDEFINED; VkFormat actual = VK_FORMAT_UNDEFINED; }; + + /** + * \brief Format lookup mode + * + * When looking up an image format, additional information + * might be needed on how the image is going to be used. + * This is used to properly map typeless formats and color + * formats to depth formats if they are used on depth images. + */ + enum class DxgiFormatMode : uint32_t { + Any = 0, + Color = 1, + Depth = 2, + }; } /** @@ -39,8 +53,20 @@ IDXGIAdapterPrivate : public IDXGIAdapter1 { virtual dxvk::Rc STDMETHODCALLTYPE GetDXVKAdapter() = 0; + /** + * \brief Maps a DXGI format to a compatible Vulkan format + * + * For color formats, the returned Vulkan format has the + * same memory layout as the DXGI format so that it can + * be mapped and copied to buffers. For depth-stencil + * formats, this is not guaranteed. + * \param [in] format The DXGI format + * \param [in] mode Format lookup mode + * \returns Vulkan format pair + */ virtual dxvk::DxgiFormatPair STDMETHODCALLTYPE LookupFormat( - DXGI_FORMAT format) = 0; + DXGI_FORMAT format, + dxvk::DxgiFormatMode mode) = 0; }; diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index b8800fb51..6e2e341f6 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -22,7 +22,7 @@ namespace dxvk { // Create swap chain for the surface DxvkSwapchainProperties swapchainProperties; swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat); - swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR; swapchainProperties.preferredBufferSize.width = bufferWidth; swapchainProperties.preferredBufferSize.height = bufferHeight; @@ -315,7 +315,7 @@ namespace dxvk { DXGI_FORMAT bufferFormat) { DxvkSwapchainProperties swapchainProperties; swapchainProperties.preferredSurfaceFormat = this->pickFormat(bufferFormat); - swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + swapchainProperties.preferredPresentMode = VK_PRESENT_MODE_FIFO_KHR; swapchainProperties.preferredBufferSize.width = bufferWidth; swapchainProperties.preferredBufferSize.height = bufferHeight; diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index a0ba3eed2..fae434ea1 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -331,7 +331,7 @@ namespace dxvk { const Rc backBuffer = m_presenter->createBackBuffer( m_desc.BufferDesc.Width, m_desc.BufferDesc.Height, - m_adapter->LookupFormat(m_desc.BufferDesc.Format).actual, + m_adapter->LookupFormat(m_desc.BufferDesc.Format, DxgiFormatMode::Color).actual, sampleCount); const Com resource