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