From 659ec7b59d990fe979acbb87351ddd3fd2920f6f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 20 Dec 2017 14:54:24 +0100 Subject: [PATCH] [d3d11] Added DXGI format properties --- src/d3d11/d3d11_device.cpp | 21 ++++---- src/d3d11/d3d11_device.h | 2 +- src/d3d11/d3d11_texture.cpp | 2 +- src/dxbc/dxbc_compiler.cpp | 7 +++ src/dxgi/dxgi_adapter.cpp | 96 +++++++++++++++++++++++++------------ src/dxgi/dxgi_adapter.h | 12 +++-- src/dxgi/dxgi_interfaces.h | 20 ++++---- src/spirv/spirv_module.cpp | 35 ++++++++++++++ src/spirv/spirv_module.h | 12 +++++ 9 files changed, 153 insertions(+), 54 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index df112bd5..7b12c2b4 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -161,10 +161,13 @@ namespace dxvk { // Fill in the view info. The view type depends solely // on the view dimension field in the view description, // not on the resource type. + const DxgiFormatInfo formatInfo = m_dxgiAdapter + ->LookupFormat(desc.Format, textureInfo.formatMode); + DxvkImageViewCreateInfo viewInfo; - viewInfo.format = m_dxgiAdapter->LookupFormat( - desc.Format, textureInfo.formatMode).actual; - viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; + viewInfo.format = formatInfo.format; + viewInfo.aspect = formatInfo.aspect; + viewInfo.swizzle = formatInfo.swizzle; switch (desc.ViewDimension) { case D3D11_SRV_DIMENSION_TEXTURE1D: @@ -306,7 +309,7 @@ namespace dxvk { // Fill in Vulkan image view info DxvkImageViewCreateInfo viewInfo; - viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Color).actual; + viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Color).format; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; switch (desc.ViewDimension) { @@ -400,7 +403,7 @@ namespace dxvk { // Fill in Vulkan image view info DxvkImageViewCreateInfo viewInfo; - viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Depth).actual; + viewInfo.format = m_dxgiAdapter->LookupFormat(desc.Format, DxgiFormatMode::Depth).format; viewInfo.aspect = imageFormatInfo(viewInfo.format)->aspectMask; switch (desc.ViewDimension) { @@ -494,7 +497,7 @@ namespace dxvk { attrib.location = entry->registerId; attrib.binding = pInputElementDescs[i].InputSlot; attrib.format = m_dxgiAdapter->LookupFormat( - pInputElementDescs[i].Format, DxgiFormatMode::Color).actual; + pInputElementDescs[i].Format, DxgiFormatMode::Color).format; attrib.offset = pInputElementDescs[i].AlignedByteOffset; // The application may choose to let the implementation @@ -886,7 +889,7 @@ namespace dxvk { // We need to check whether the format is VkFormat format = m_dxgiAdapter->LookupFormat( - Format, DxgiFormatMode::Any).actual; + Format, DxgiFormatMode::Any).format; if (format == VK_FORMAT_UNDEFINED) { Logger::err(str::format("D3D11: Unsupported format: ", Format)); @@ -1024,7 +1027,7 @@ namespace dxvk { } - DxgiFormatPair STDMETHODCALLTYPE D3D11Device::LookupFormat( + DxgiFormatInfo STDMETHODCALLTYPE D3D11Device::LookupFormat( DXGI_FORMAT format, DxgiFormatMode mode) const { return m_dxgiAdapter->LookupFormat(format, mode); @@ -1382,7 +1385,7 @@ namespace dxvk { HRESULT D3D11Device::GetFormatSupportFlags(DXGI_FORMAT Format, UINT* pFlags) const { - const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).actual; + const VkFormat fmt = m_dxgiAdapter->LookupFormat(Format, DxgiFormatMode::Any).format; const VkFormatProperties fmtInfo = m_dxvkAdapter->formatProperties(fmt); if (fmt == VK_FORMAT_UNDEFINED) diff --git a/src/d3d11/d3d11_device.h b/src/d3d11/d3d11_device.h index 70cb791b..0ccbd47f 100644 --- a/src/d3d11/d3d11_device.h +++ b/src/d3d11/d3d11_device.h @@ -228,7 +228,7 @@ namespace dxvk { VkPipelineStageFlags GetEnabledShaderStages() const; - DxgiFormatPair STDMETHODCALLTYPE LookupFormat( + DxgiFormatInfo STDMETHODCALLTYPE LookupFormat( DXGI_FORMAT format, DxgiFormatMode mode) const; diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 672e4f3a..47f63a2d 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -24,7 +24,7 @@ namespace dxvk { DxvkImageCreateInfo info; info.type = VK_IMAGE_TYPE_2D; info.format = pDevice->LookupFormat( - pDesc->Format, m_formatMode).actual; + pDesc->Format, m_formatMode).format; info.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT; info.sampleCount = VK_SAMPLE_COUNT_1_BIT; info.extent.width = pDesc->Width; diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index e715ef8e..1e79b9b6 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -1253,6 +1253,13 @@ namespace dxvk { sampledImageId, coord.id); } break; + case DxbcOpcode::SampleC: { + result.id = m_module.opImageSampleDrefImplicitLod( + getVectorTypeId(result.type), + sampledImageId, coord.id, + referenceValue.id); + } break; + case DxbcOpcode::SampleClz: { result.id = m_module.opImageSampleDrefExplicitLod( getVectorTypeId(result.type), diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index f317b1f7..92672dff 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -138,7 +138,7 @@ namespace dxvk { } - DxgiFormatPair STDMETHODCALLTYPE DxgiAdapter::LookupFormat(DXGI_FORMAT format, DxgiFormatMode mode) { + DxgiFormatInfo 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); @@ -153,26 +153,52 @@ namespace dxvk { return depth->second; } - return DxgiFormatPair(); + Logger::err(str::format("DxgiAdapter: No format mapping for ", format)); + return DxgiFormatInfo(); } void DxgiAdapter::AddColorFormat( DXGI_FORMAT srcFormat, VkFormat dstFormat) { - DxgiFormatPair formatPair; - formatPair.wanted = dstFormat; - formatPair.actual = dstFormat; + DxgiFormatInfo formatPair; + formatPair.format = dstFormat; + formatPair.aspect = VK_IMAGE_ASPECT_COLOR_BIT; + formatPair.swizzle = { + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + }; + m_colorFormats.insert(std::make_pair(srcFormat, formatPair)); + } + + + void DxgiAdapter::AddColorFormat( + DXGI_FORMAT srcFormat, + VkFormat dstFormat, + VkComponentMapping swizzle) { + DxgiFormatInfo formatPair; + formatPair.format = dstFormat; + formatPair.aspect = VK_IMAGE_ASPECT_COLOR_BIT; + formatPair.swizzle = swizzle; m_colorFormats.insert(std::make_pair(srcFormat, formatPair)); } void DxgiAdapter::AddDepthFormat( DXGI_FORMAT srcFormat, - VkFormat dstFormat) { - DxgiFormatPair formatPair; - formatPair.wanted = dstFormat; - formatPair.actual = dstFormat; + VkFormat dstFormat, + VkImageAspectFlags srvAspect) { + DxgiFormatInfo formatPair; + formatPair.format = dstFormat; + formatPair.aspect = srvAspect; + formatPair.swizzle = { + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + VK_COMPONENT_SWIZZLE_IDENTITY, + }; m_depthFormats.insert(std::make_pair(srcFormat, formatPair)); } @@ -263,10 +289,18 @@ namespace dxvk { AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_UNORM); AddColorFormat(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB); - // TODO implement component swizzle - 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_B8G8R8X8_UNORM, VK_FORMAT_B8G8R8A8_UNORM, + { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }); + + AddColorFormat(DXGI_FORMAT_B8G8R8X8_TYPELESS, VK_FORMAT_B8G8R8A8_UNORM, + { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }); + + AddColorFormat(DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, VK_FORMAT_B8G8R8A8_SRGB, + { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }); + // AddColorFormat(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, VK_FORMAT_UNDEFINED); /***********************************************************************************/ @@ -301,30 +335,32 @@ namespace dxvk { /***********************************************************************************/ /* 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_D16_UNORM, VK_FORMAT_D16_UNORM, 0); + AddDepthFormat(DXGI_FORMAT_R16_TYPELESS, VK_FORMAT_D16_UNORM, 0); + AddDepthFormat(DXGI_FORMAT_R16_UNORM, VK_FORMAT_D16_UNORM, VK_IMAGE_ASPECT_DEPTH_BIT); - 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, VK_FORMAT_D32_SFLOAT, 0); + AddDepthFormat(DXGI_FORMAT_R32_TYPELESS, VK_FORMAT_D32_SFLOAT, 0); + AddDepthFormat(DXGI_FORMAT_R32_FLOAT, VK_FORMAT_D32_SFLOAT, VK_IMAGE_ASPECT_DEPTH_BIT); - 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); + AddDepthFormat(DXGI_FORMAT_D32_FLOAT_S8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 0); + AddDepthFormat(DXGI_FORMAT_R32G8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 0); + AddDepthFormat(DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT); + AddDepthFormat(DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT); // 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); + AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, 0); + AddDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, 0); + AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT); + AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT); } 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); + AddDepthFormat(DXGI_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, 0); + AddDepthFormat(DXGI_FORMAT_R24G8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, 0); + AddDepthFormat(DXGI_FORMAT_R24_UNORM_X8_TYPELESS, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_DEPTH_BIT); + AddDepthFormat(DXGI_FORMAT_X24_TYPELESS_G8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_IMAGE_ASPECT_STENCIL_BIT); } } @@ -332,7 +368,7 @@ namespace dxvk { bool DxgiAdapter::HasFormatSupport( VkFormat format, VkFormatFeatureFlags features) const { - VkFormatProperties info = m_adapter->formatProperties(format); + const VkFormatProperties info = m_adapter->formatProperties(format); return ((info.optimalTilingFeatures | info.bufferFeatures) & features) == features; } diff --git a/src/dxgi/dxgi_adapter.h b/src/dxgi/dxgi_adapter.h index 3e5d5ec9..06a95873 100644 --- a/src/dxgi/dxgi_adapter.h +++ b/src/dxgi/dxgi_adapter.h @@ -48,12 +48,12 @@ namespace dxvk { Rc STDMETHODCALLTYPE GetDXVKAdapter() final; - DxgiFormatPair STDMETHODCALLTYPE LookupFormat( + DxgiFormatInfo STDMETHODCALLTYPE LookupFormat( DXGI_FORMAT format, DxgiFormatMode mode) final; private: - using FormatMap = std::unordered_map; + using FormatMap = std::unordered_map; Com m_factory; Rc m_adapter; @@ -65,9 +65,15 @@ namespace dxvk { DXGI_FORMAT srcFormat, VkFormat dstFormat); + void AddColorFormat( + DXGI_FORMAT srcFormat, + VkFormat dstFormat, + VkComponentMapping swizzle); + void AddDepthFormat( DXGI_FORMAT srcFormat, - VkFormat dstFormat); + VkFormat dstFormat, + VkImageAspectFlags srvAspect); void SetupFormatTable(); diff --git a/src/dxgi/dxgi_interfaces.h b/src/dxgi/dxgi_interfaces.h index c52ab789..a0896911 100644 --- a/src/dxgi/dxgi_interfaces.h +++ b/src/dxgi/dxgi_interfaces.h @@ -12,17 +12,17 @@ namespace dxvk { class DxvkImage; /** - * \brief Format pair + * \brief Format info * - * For a DXGI format, this stores two Vulkan formats: - * The format that directly corresponds to the DXGI - * format, and a similar format that the device can - * use. If the device supports the desired format, - * both formats will be equal. + * Stores a Vulkan image format for a given + * DXGI format and some additional information + * on how resources with the particular format + * are supposed to be used. */ - struct DxgiFormatPair { - VkFormat wanted = VK_FORMAT_UNDEFINED; - VkFormat actual = VK_FORMAT_UNDEFINED; + struct DxgiFormatInfo { + VkFormat format; + VkImageAspectFlags aspect; + VkComponentMapping swizzle; }; /** @@ -64,7 +64,7 @@ IDXGIAdapterPrivate : public IDXGIAdapter1 { * \param [in] mode Format lookup mode * \returns Vulkan format pair */ - virtual dxvk::DxgiFormatPair STDMETHODCALLTYPE LookupFormat( + virtual dxvk::DxgiFormatInfo STDMETHODCALLTYPE LookupFormat( DXGI_FORMAT format, dxvk::DxgiFormatMode mode) = 0; }; diff --git a/src/spirv/spirv_module.cpp b/src/spirv/spirv_module.cpp index b29c9926..4e11c226 100644 --- a/src/spirv/spirv_module.cpp +++ b/src/spirv/spirv_module.cpp @@ -1533,6 +1533,41 @@ namespace dxvk { } + uint32_t SpirvModule::opImageSampleExplicitLod( + uint32_t resultType, + uint32_t sampledImage, + uint32_t coordinates, + uint32_t lod) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpImageSampleExplicitLod, 7); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(sampledImage); + m_code.putWord(coordinates); + m_code.putWord(spv::ImageOperandsLodMask); + m_code.putWord(lod); + return resultId; + } + + + uint32_t SpirvModule::opImageSampleDrefImplicitLod( + uint32_t resultType, + uint32_t sampledImage, + uint32_t coordinates, + uint32_t reference) { + uint32_t resultId = this->allocateId(); + + m_code.putIns (spv::OpImageSampleDrefImplicitLod, 6); + m_code.putWord(resultType); + m_code.putWord(resultId); + m_code.putWord(sampledImage); + m_code.putWord(coordinates); + m_code.putWord(reference); + return resultId; + } + + uint32_t SpirvModule::opImageSampleDrefExplicitLod( uint32_t resultType, uint32_t sampledImage, diff --git a/src/spirv/spirv_module.h b/src/spirv/spirv_module.h index 6a816a17..414f4e0d 100644 --- a/src/spirv/spirv_module.h +++ b/src/spirv/spirv_module.h @@ -520,6 +520,18 @@ namespace dxvk { uint32_t sampledImage, uint32_t coordinates); + uint32_t opImageSampleExplicitLod( + uint32_t resultType, + uint32_t sampledImage, + uint32_t coordinates, + uint32_t lod); + + uint32_t opImageSampleDrefImplicitLod( + uint32_t resultType, + uint32_t sampledImage, + uint32_t coordinates, + uint32_t reference); + uint32_t opImageSampleDrefExplicitLod( uint32_t resultType, uint32_t sampledImage,