diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 5e22c5c8..b25cd453 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -391,8 +391,10 @@ namespace dxvk { D3D11_MAPPED_SUBRESOURCE* pMappedResource) { const Rc mappedImage = pResource->GetImage(); const Rc mappedBuffer = pResource->GetMappedBuffer(Subresource); + + auto mapMode = pResource->GetMapMode(); - if (unlikely(pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) { + if (unlikely(mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) { Logger::err("D3D11: Cannot map a device-local image"); return E_INVALIDARG; } @@ -416,32 +418,21 @@ namespace dxvk { auto formatInfo = imageFormatInfo(packedFormat); auto subresource = pResource->GetSubresourceFromIndex( formatInfo->aspectMask, Subresource); - - if (pResource->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { + void* mapPtr; + + if (mapMode == D3D11_COMMON_TEXTURE_MAP_MODE_DIRECT) { // Wait for the resource to become available if (!WaitForResource(mappedImage, MapType, MapFlags)) return DXGI_ERROR_WAS_STILL_DRAWING; - // Mark the given subresource as mapped - pResource->SetMapType(Subresource, MapType); - // Query the subresource's memory layout and hope that // the application respects the returned pitch values. - if (pMappedResource) { - auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource); - pMappedResource->pData = mappedImage->mapPtr(layout.Offset); - pMappedResource->RowPitch = layout.RowPitch; - pMappedResource->DepthPitch = layout.DepthPitch; - } - - return S_OK; + mapPtr = mappedImage->mapPtr(0); } else { - DxvkBufferSliceHandle physSlice; - if (MapType == D3D11_MAP_WRITE_DISCARD) { // We do not have to preserve the contents of the // buffer if the entire image gets discarded. - physSlice = mappedBuffer->allocSlice(); + DxvkBufferSliceHandle physSlice = pResource->DiscardSlice(Subresource); EmitCs([ cImageBuffer = mappedBuffer, @@ -449,6 +440,8 @@ namespace dxvk { ] (DxvkContext* ctx) { ctx->invalidateBuffer(cImageBuffer, cBufferSlice); }); + + mapPtr = physSlice.mapPtr; } else { // When using any map mode which requires the image contents // to be preserved, and if the GPU has write access to the @@ -463,22 +456,21 @@ namespace dxvk { if (!WaitForResource(mappedBuffer, MapType, MapFlags)) return DXGI_ERROR_WAS_STILL_DRAWING; - physSlice = mappedBuffer->getSliceHandle(); + mapPtr = pResource->GetMappedSlice(Subresource).mapPtr; } - - // Mark the given subresource as mapped - pResource->SetMapType(Subresource, MapType); - - // Set up map pointer. Data is tightly packed within the mapped buffer. - if (pMappedResource) { - auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource); - pMappedResource->pData = reinterpret_cast(physSlice.mapPtr) + layout.Offset; - pMappedResource->RowPitch = layout.RowPitch; - pMappedResource->DepthPitch = layout.DepthPitch; - } - - return S_OK; } + + // Mark the given subresource as mapped + pResource->SetMapType(Subresource, MapType); + + if (pMappedResource) { + auto layout = pResource->GetSubresourceLayout(formatInfo->aspectMask, Subresource); + pMappedResource->pData = reinterpret_cast(mapPtr) + layout.Offset; + pMappedResource->RowPitch = layout.RowPitch; + pMappedResource->DepthPitch = layout.DepthPitch; + } + + return S_OK; } diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 4d31db93..563c10c9 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -542,7 +542,7 @@ namespace dxvk { } - Rc D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const { + D3D11CommonTexture::MappedBuffer D3D11CommonTexture::CreateMappedBuffer(UINT MipLevel) const { const DxvkFormatInfo* formatInfo = imageFormatInfo( m_device->LookupPackedFormat(m_desc.Format, GetFormatMode()).Format); @@ -561,7 +561,10 @@ namespace dxvk { if (m_desc.Usage == D3D11_USAGE_STAGING) memType |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; - return m_device->GetDXVKDevice()->createBuffer(info, memType); + MappedBuffer result; + result.buffer = m_device->GetDXVKDevice()->createBuffer(info, memType); + result.slice = result.buffer->getSliceHandle(); + return result; } diff --git a/src/d3d11/d3d11_texture.h b/src/d3d11/d3d11_texture.h index 29e27767..fda60350 100644 --- a/src/d3d11/d3d11_texture.h +++ b/src/d3d11/d3d11_texture.h @@ -168,9 +168,37 @@ namespace dxvk { */ Rc GetMappedBuffer(UINT Subresource) const { return Subresource < m_buffers.size() - ? m_buffers[Subresource] + ? m_buffers[Subresource].buffer : Rc(); } + + /** + * \brief Discards mapped buffer slice for a given subresource + * + * \param [in] Subresource Subresource to discard + * \returns Newly allocated mapped buffer slice + */ + DxvkBufferSliceHandle DiscardSlice(UINT Subresource) { + if (Subresource < m_buffers.size()) { + DxvkBufferSliceHandle slice = m_buffers[Subresource].buffer->allocSlice(); + m_buffers[Subresource].slice = slice; + return slice; + } else { + return DxvkBufferSliceHandle(); + } + } + + /** + * \brief Retrieves mapped buffer slice for a given subresource + * + * \param [in] Subresource Subresource index to query + * \returns Currently mapped buffer slice + */ + DxvkBufferSliceHandle GetMappedSlice(UINT Subresource) const { + return Subresource < m_buffers.size() + ? m_buffers[Subresource].slice + : DxvkBufferSliceHandle(); + } /** * \brief Checks whether we can update the mapped buffer early @@ -258,6 +286,11 @@ namespace dxvk { private: + struct MappedBuffer { + Rc buffer; + DxvkBufferSliceHandle slice; + }; + D3D11Device* const m_device; D3D11_RESOURCE_DIMENSION m_dimension; D3D11_COMMON_TEXTURE_DESC m_desc; @@ -265,10 +298,10 @@ namespace dxvk { DXGI_USAGE m_dxgiUsage; Rc m_image; - std::vector> m_buffers; + std::vector m_buffers; std::vector m_mapTypes; - Rc CreateMappedBuffer( + MappedBuffer CreateMappedBuffer( UINT MipLevel) const; BOOL CheckImageSupport(