From 3168626f4be39672ec2ba626ed6c26e22a8f9c62 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 20 May 2019 15:56:31 +0200 Subject: [PATCH] [d3d11] Support mapping multiple image subresources at the same time Fixes #1066. --- src/d3d11/d3d11_context.cpp | 6 ++- src/d3d11/d3d11_context_imm.cpp | 29 +++++++----- src/d3d11/d3d11_texture.cpp | 19 ++++++-- src/d3d11/d3d11_texture.h | 83 +++++++++++++++------------------ 4 files changed, 74 insertions(+), 63 deletions(-) diff --git a/src/d3d11/d3d11_context.cpp b/src/d3d11/d3d11_context.cpp index 57bdfb7ac..039c2904a 100644 --- a/src/d3d11/d3d11_context.cpp +++ b/src/d3d11/d3d11_context.cpp @@ -3686,8 +3686,12 @@ namespace dxvk { void D3D11DeviceContext::UpdateMappedBuffer( const D3D11CommonTexture* pTexture, VkImageSubresource Subresource) { + UINT SubresourceIndex = D3D11CalcSubresource( + Subresource.mipLevel, Subresource.arrayLayer, + pTexture->Desc()->MipLevels); + Rc mappedImage = pTexture->GetImage(); - Rc mappedBuffer = pTexture->GetMappedBuffer(); + Rc mappedBuffer = pTexture->GetMappedBuffer(SubresourceIndex); VkFormat packedFormat = m_parent->LookupPackedFormat( pTexture->Desc()->Format, pTexture->GetFormatMode()).Format; diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 6a6f47015..199714d41 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -332,21 +332,21 @@ namespace dxvk { UINT MapFlags, D3D11_MAPPED_SUBRESOURCE* pMappedResource) { const Rc mappedImage = pResource->GetImage(); - const Rc mappedBuffer = pResource->GetMappedBuffer(); + const Rc mappedBuffer = pResource->GetMappedBuffer(Subresource); if (unlikely(pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) { Logger::err("D3D11: Cannot map a device-local image"); return E_INVALIDARG; } + pResource->SetMapType(Subresource, MapType); + VkFormat packedFormat = m_parent->LookupPackedFormat( pResource->Desc()->Format, pResource->GetFormatMode()).Format; auto formatInfo = imageFormatInfo(packedFormat); auto subresource = pResource->GetSubresourceFromIndex( - formatInfo->aspectMask, Subresource); - - pResource->SetMappedSubresource(subresource, MapType); + formatInfo->aspectMask, Subresource); if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { const VkImageType imageType = mappedImage->info().type; @@ -408,17 +408,26 @@ namespace dxvk { void D3D11ImmediateContext::UnmapImage( D3D11CommonTexture* pResource, UINT Subresource) { - if (pResource->GetMapType() == D3D11_MAP_READ) + D3D11_MAP mapType = pResource->GetMapType(Subresource); + pResource->SetMapType(Subresource, D3D11_MAP(~0u)); + + if (mapType == D3D11_MAP(~0u) + || mapType == D3D11_MAP_READ) return; if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) { // Now that data has been written into the buffer, // we need to copy its contents into the image const Rc mappedImage = pResource->GetImage(); - const Rc mappedBuffer = pResource->GetMappedBuffer(); - - VkImageSubresource subresource = pResource->GetMappedSubresource(); - + const Rc mappedBuffer = pResource->GetMappedBuffer(Subresource); + + VkFormat packedFormat = m_parent->LookupPackedFormat( + pResource->Desc()->Format, pResource->GetFormatMode()).Format; + + auto formatInfo = imageFormatInfo(packedFormat); + auto subresource = pResource->GetSubresourceFromIndex( + formatInfo->aspectMask, Subresource); + VkExtent3D levelExtent = mappedImage ->mipLevelExtent(subresource.mipLevel); @@ -447,8 +456,6 @@ namespace dxvk { } }); } - - pResource->ClearMappedSubresource(); } diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index c06873825..853a62796 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -164,8 +164,14 @@ namespace dxvk { } // If necessary, create the mapped linear buffer - if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) - m_buffer = CreateMappedBuffer(); + for (uint32_t i = 0; i < m_desc.ArraySize; i++) { + for (uint32_t j = 0; j < m_desc.MipLevels; j++) { + if (m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER) + m_buffers.push_back(CreateMappedBuffer(j)); + if (m_mapMode != D3D11_COMMON_TEXTURE_MAP_MODE_NONE) + m_mapTypes.push_back(D3D11_MAP(~0u)); + } + } // Create the image on a host-visible memory type // in case it is going to be mapped directly. @@ -404,13 +410,16 @@ namespace dxvk { } - Rc D3D11CommonTexture::CreateMappedBuffer() const { + Rc D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const { const DxvkFormatInfo* formatInfo = imageFormatInfo( m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format); - const VkExtent3D blockCount = util::computeBlockCount( + const VkExtent3D mipExtent = util::computeMipLevelExtent( VkExtent3D { m_desc.Width, m_desc.Height, m_desc.Depth }, - formatInfo->blockSize); + MipLevel); + + const VkExtent3D blockCount = util::computeBlockCount( + mipExtent, formatInfo->blockSize); DxvkBufferCreateInfo info; info.size = formatInfo->elementSize diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 597aa7a29..19dabd5f8 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -82,6 +82,29 @@ namespace dxvk { D3D11_COMMON_TEXTURE_MAP_MODE GetMapMode() const { return m_mapMode; } + + /** + * \brief Map type of a given subresource + * + * \param [in] Subresource Subresource index + * \returns Current map mode of that subresource + */ + D3D11_MAP GetMapType(UINT Subresource) const { + return Subresource < m_mapTypes.size() + ? D3D11_MAP(m_mapTypes[Subresource]) + : D3D11_MAP(~0u); + } + + /** + * \brief Sets map type for a given subresource + * + * \param [in] Subresource The subresource + * \param [in] MapType The map type + */ + void SetMapType(UINT Subresource, D3D11_MAP MapType) { + if (Subresource < m_mapTypes.size()) + m_mapTypes[Subresource] = MapType; + } /** * \brief The DXVK image @@ -92,45 +115,17 @@ namespace dxvk { } /** - * \brief The DXVK buffer - * \returns The DXVK buffer + * \brief Mapped subresource buffer + * + * \param [in] Subresource Subresource index + * \returns Mapped subresource buffer */ - Rc GetMappedBuffer() const { - return m_buffer; + Rc GetMappedBuffer(UINT Subresource) const { + return Subresource < m_buffers.size() + ? m_buffers[Subresource] + : Rc(); } - /** - * \brief Currently mapped subresource - * \returns Mapped subresource - */ - VkImageSubresource GetMappedSubresource() const { - return m_mappedSubresource; - } - - /** - * \brief Current map type - */ - D3D11_MAP GetMapType() const { - return m_mapType; - } - - /** - * \brief Sets mapped subresource - * \param [in] subresource THe subresource - */ - void SetMappedSubresource(VkImageSubresource Subresource, D3D11_MAP MapType) { - m_mappedSubresource = Subresource; - m_mapType = MapType; - } - - /** - * \brief Resets mapped subresource - * Marks the texture as not mapped. - */ - void ClearMappedSubresource() { - m_mappedSubresource = VkImageSubresource { }; - } - /** * \brief Checks whether we can update the mapped buffer early * @@ -142,9 +137,7 @@ namespace dxvk { bool CanUpdateMappedBufferEarly() const { return m_mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_BUFFER && (m_desc.BindFlags & ~D3D11_BIND_SHADER_RESOURCE) == 0 - && m_desc.Usage == D3D11_USAGE_STAGING - && m_desc.MipLevels == 1 - && m_desc.ArraySize == 1; + && (m_desc.Usage == D3D11_USAGE_STAGING); } /** @@ -208,14 +201,12 @@ namespace dxvk { D3D11_COMMON_TEXTURE_DESC m_desc; D3D11_COMMON_TEXTURE_MAP_MODE m_mapMode; - Rc m_image; - Rc m_buffer; + Rc m_image; + std::vector> m_buffers; + std::vector m_mapTypes; - VkImageSubresource m_mappedSubresource - = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0 }; - D3D11_MAP m_mapType = D3D11_MAP_READ; - - Rc CreateMappedBuffer() const; + Rc CreateMappedBuffer( + UINT MipLevel) const; BOOL CheckImageSupport( const DxvkImageCreateInfo* pImageInfo,