diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 739840ef..9d91ba9c 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -132,122 +132,6 @@ namespace dxvk { } - void STDMETHODCALLTYPE D3D11DeviceContext::ResolveSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format) { - D3D10DeviceLock lock = LockContext(); - - bool isSameSubresource = pDstResource == pSrcResource - && DstSubresource == SrcSubresource; - - if (!pDstResource || !pSrcResource || isSameSubresource) - return; - - D3D11_RESOURCE_DIMENSION dstResourceType; - D3D11_RESOURCE_DIMENSION srcResourceType; - - pDstResource->GetType(&dstResourceType); - pSrcResource->GetType(&srcResourceType); - - if (dstResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D - || srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { - Logger::err(str::format( - "D3D11: ResolveSubresource: Incompatible resources", - "\n Dst resource type: ", dstResourceType, - "\n Src resource type: ", srcResourceType)); - return; - } - - auto dstTexture = static_cast(pDstResource); - auto srcTexture = static_cast(pSrcResource); - - D3D11_TEXTURE2D_DESC dstDesc; - D3D11_TEXTURE2D_DESC srcDesc; - - dstTexture->GetDesc(&dstDesc); - srcTexture->GetDesc(&srcDesc); - - if (dstDesc.SampleDesc.Count != 1) { - Logger::err(str::format( - "D3D11: ResolveSubresource: Invalid sample counts", - "\n Dst sample count: ", dstDesc.SampleDesc.Count, - "\n Src sample count: ", srcDesc.SampleDesc.Count)); - return; - } - - D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource); - D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource); - - const DXGI_VK_FORMAT_INFO dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DXGI_VK_FORMAT_MODE_ANY); - const DXGI_VK_FORMAT_INFO srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DXGI_VK_FORMAT_MODE_ANY); - - auto dstVulkanFormatInfo = lookupFormatInfo(dstFormatInfo.Format); - auto srcVulkanFormatInfo = lookupFormatInfo(srcFormatInfo.Format); - - if (DstSubresource >= dstTextureInfo->CountSubresources() - || SrcSubresource >= srcTextureInfo->CountSubresources()) - return; - - const VkImageSubresource dstSubresource = - dstTextureInfo->GetSubresourceFromIndex( - dstVulkanFormatInfo->aspectMask, DstSubresource); - - const VkImageSubresource srcSubresource = - srcTextureInfo->GetSubresourceFromIndex( - srcVulkanFormatInfo->aspectMask, SrcSubresource); - - const VkImageSubresourceLayers dstSubresourceLayers = { - dstSubresource.aspectMask, - dstSubresource.mipLevel, - dstSubresource.arrayLayer, 1 }; - - const VkImageSubresourceLayers srcSubresourceLayers = { - srcSubresource.aspectMask, - srcSubresource.mipLevel, - srcSubresource.arrayLayer, 1 }; - - if (srcDesc.SampleDesc.Count == 1 || m_parent->GetOptions()->disableMsaa) { - EmitCs([ - cDstImage = dstTextureInfo->GetImage(), - cSrcImage = srcTextureInfo->GetImage(), - cDstLayers = dstSubresourceLayers, - cSrcLayers = srcSubresourceLayers - ] (DxvkContext* ctx) { - ctx->copyImage( - cDstImage, cDstLayers, VkOffset3D { 0, 0, 0 }, - cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 }, - cDstImage->mipLevelExtent(cDstLayers.mipLevel)); - }); - } else { - const VkFormat format = m_parent->LookupFormat( - Format, DXGI_VK_FORMAT_MODE_ANY).Format; - - EmitCs([ - cDstImage = dstTextureInfo->GetImage(), - cSrcImage = srcTextureInfo->GetImage(), - cDstSubres = dstSubresourceLayers, - cSrcSubres = srcSubresourceLayers, - cFormat = format - ] (DxvkContext* ctx) { - VkImageResolve region; - region.srcSubresource = cSrcSubres; - region.srcOffset = VkOffset3D { 0, 0, 0 }; - region.dstSubresource = cDstSubres; - region.dstOffset = VkOffset3D { 0, 0, 0 }; - region.extent = cDstImage->mipLevelExtent(cDstSubres.mipLevel); - - ctx->resolveImage(cDstImage, cSrcImage, region, cFormat); - }); - } - - if (dstTextureInfo->HasSequenceNumber()) - TrackTextureSequenceNumber(dstTextureInfo, DstSubresource); - } - - void STDMETHODCALLTYPE D3D11DeviceContext::DrawAuto() { D3D10DeviceLock lock = LockContext(); diff --git a/src/d3d11/d3d11_context.h b/src/d3d11/d3d11_context.h index b0c96be0..8612298c 100644 --- a/src/d3d11/d3d11_context.h +++ b/src/d3d11/d3d11_context.h @@ -84,13 +84,6 @@ namespace dxvk { FLOAT STDMETHODCALLTYPE GetResourceMinLOD( ID3D11Resource* pResource); - void STDMETHODCALLTYPE ResolveSubresource( - ID3D11Resource* pDstResource, - UINT DstSubresource, - ID3D11Resource* pSrcResource, - UINT SrcSubresource, - DXGI_FORMAT Format); - void STDMETHODCALLTYPE DrawAuto(); void STDMETHODCALLTYPE Draw( diff --git a/src/d3d11/d3d11_context_common.cpp b/src/d3d11/d3d11_context_common.cpp index df8ec61b..2228df2a 100644 --- a/src/d3d11/d3d11_context_common.cpp +++ b/src/d3d11/d3d11_context_common.cpp @@ -899,6 +899,123 @@ namespace dxvk { } + template + void STDMETHODCALLTYPE D3D11CommonContext::ResolveSubresource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + DXGI_FORMAT Format) { + D3D10DeviceLock lock = LockContext(); + + bool isSameSubresource = pDstResource == pSrcResource + && DstSubresource == SrcSubresource; + + if (!pDstResource || !pSrcResource || isSameSubresource) + return; + + D3D11_RESOURCE_DIMENSION dstResourceType; + D3D11_RESOURCE_DIMENSION srcResourceType; + + pDstResource->GetType(&dstResourceType); + pSrcResource->GetType(&srcResourceType); + + if (dstResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D + || srcResourceType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { + Logger::err(str::format( + "D3D11: ResolveSubresource: Incompatible resources", + "\n Dst resource type: ", dstResourceType, + "\n Src resource type: ", srcResourceType)); + return; + } + + auto dstTexture = static_cast(pDstResource); + auto srcTexture = static_cast(pSrcResource); + + D3D11_TEXTURE2D_DESC dstDesc; + D3D11_TEXTURE2D_DESC srcDesc; + + dstTexture->GetDesc(&dstDesc); + srcTexture->GetDesc(&srcDesc); + + if (dstDesc.SampleDesc.Count != 1) { + Logger::err(str::format( + "D3D11: ResolveSubresource: Invalid sample counts", + "\n Dst sample count: ", dstDesc.SampleDesc.Count, + "\n Src sample count: ", srcDesc.SampleDesc.Count)); + return; + } + + D3D11CommonTexture* dstTextureInfo = GetCommonTexture(pDstResource); + D3D11CommonTexture* srcTextureInfo = GetCommonTexture(pSrcResource); + + const DXGI_VK_FORMAT_INFO dstFormatInfo = m_parent->LookupFormat(dstDesc.Format, DXGI_VK_FORMAT_MODE_ANY); + const DXGI_VK_FORMAT_INFO srcFormatInfo = m_parent->LookupFormat(srcDesc.Format, DXGI_VK_FORMAT_MODE_ANY); + + auto dstVulkanFormatInfo = lookupFormatInfo(dstFormatInfo.Format); + auto srcVulkanFormatInfo = lookupFormatInfo(srcFormatInfo.Format); + + if (DstSubresource >= dstTextureInfo->CountSubresources() + || SrcSubresource >= srcTextureInfo->CountSubresources()) + return; + + const VkImageSubresource dstSubresource = + dstTextureInfo->GetSubresourceFromIndex( + dstVulkanFormatInfo->aspectMask, DstSubresource); + + const VkImageSubresource srcSubresource = + srcTextureInfo->GetSubresourceFromIndex( + srcVulkanFormatInfo->aspectMask, SrcSubresource); + + const VkImageSubresourceLayers dstSubresourceLayers = { + dstSubresource.aspectMask, + dstSubresource.mipLevel, + dstSubresource.arrayLayer, 1 }; + + const VkImageSubresourceLayers srcSubresourceLayers = { + srcSubresource.aspectMask, + srcSubresource.mipLevel, + srcSubresource.arrayLayer, 1 }; + + if (srcDesc.SampleDesc.Count == 1 || m_parent->GetOptions()->disableMsaa) { + EmitCs([ + cDstImage = dstTextureInfo->GetImage(), + cSrcImage = srcTextureInfo->GetImage(), + cDstLayers = dstSubresourceLayers, + cSrcLayers = srcSubresourceLayers + ] (DxvkContext* ctx) { + ctx->copyImage( + cDstImage, cDstLayers, VkOffset3D { 0, 0, 0 }, + cSrcImage, cSrcLayers, VkOffset3D { 0, 0, 0 }, + cDstImage->mipLevelExtent(cDstLayers.mipLevel)); + }); + } else { + const VkFormat format = m_parent->LookupFormat( + Format, DXGI_VK_FORMAT_MODE_ANY).Format; + + EmitCs([ + cDstImage = dstTextureInfo->GetImage(), + cSrcImage = srcTextureInfo->GetImage(), + cDstSubres = dstSubresourceLayers, + cSrcSubres = srcSubresourceLayers, + cFormat = format + ] (DxvkContext* ctx) { + VkImageResolve region; + region.srcSubresource = cSrcSubres; + region.srcOffset = VkOffset3D { 0, 0, 0 }; + region.dstSubresource = cDstSubres; + region.dstOffset = VkOffset3D { 0, 0, 0 }; + region.extent = cDstImage->mipLevelExtent(cDstSubres.mipLevel); + + ctx->resolveImage(cDstImage, cSrcImage, region, cFormat); + }); + } + + if (dstTextureInfo->HasSequenceNumber()) + TrackTextureSequenceNumber(dstTextureInfo, DstSubresource); + } + + template void STDMETHODCALLTYPE D3D11CommonContext::UpdateSubresource( ID3D11Resource* pDstResource, diff --git a/src/d3d11/d3d11_context_common.h b/src/d3d11/d3d11_context_common.h index dea76d44..aab3cd37 100644 --- a/src/d3d11/d3d11_context_common.h +++ b/src/d3d11/d3d11_context_common.h @@ -136,6 +136,13 @@ namespace dxvk { void STDMETHODCALLTYPE GenerateMips( ID3D11ShaderResourceView* pShaderResourceView); + void STDMETHODCALLTYPE ResolveSubresource( + ID3D11Resource* pDstResource, + UINT DstSubresource, + ID3D11Resource* pSrcResource, + UINT SrcSubresource, + DXGI_FORMAT Format); + void STDMETHODCALLTYPE UpdateSubresource( ID3D11Resource* pDstResource, UINT DstSubresource,