From 8584fc772294217f55de987218d63be92af4ba94 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 2 Nov 2024 13:56:26 +0100 Subject: [PATCH] [d3d11] Simplify mapped resource tracking on deferred context --- src/d3d11/d3d11_buffer.cpp | 4 ++- src/d3d11/d3d11_buffer.h | 6 ++++ src/d3d11/d3d11_context_def.cpp | 64 +++++++++++++++------------------ src/d3d11/d3d11_context_def.h | 22 +++--------- 4 files changed, 42 insertions(+), 54 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index 8f3ed95cb..bcef8a1c6 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -97,8 +97,8 @@ namespace dxvk { m_11on12.Resource->Map(0, nullptr, &importInfo.mapPtr); m_buffer = m_parent->GetDXVKDevice()->importBuffer(info, importInfo, GetMemoryFlags()); + m_cookie = m_buffer->cookie(); m_mapPtr = m_buffer->mapPtr(0); - m_mapMode = DetermineMapMode(m_buffer->memFlags()); } else if (!(pDesc->MiscFlags & D3D11_RESOURCE_MISC_TILE_POOL)) { VkMemoryPropertyFlags memoryFlags = GetMemoryFlags(); @@ -107,11 +107,13 @@ namespace dxvk { // Create the buffer and set the entire buffer slice as mapped, // so that we only have to update it when invalidating the buffer m_buffer = m_parent->GetDXVKDevice()->createBuffer(info, memoryFlags); + m_cookie = m_buffer->cookie(); m_mapPtr = m_buffer->mapPtr(0); } else { m_sparseAllocator = m_parent->GetDXVKDevice()->createSparsePageAllocator(); m_sparseAllocator->setCapacity(info.size / SparseMemoryPageSize); + m_cookie = 0u; m_mapPtr = nullptr; m_mapMode = D3D11_COMMON_BUFFER_MAP_MODE_NONE; } diff --git a/src/d3d11/d3d11_buffer.h b/src/d3d11/d3d11_buffer.h index c2daed447..b65df66a6 100644 --- a/src/d3d11/d3d11_buffer.h +++ b/src/d3d11/d3d11_buffer.h @@ -77,6 +77,10 @@ namespace dxvk { return m_mapMode; } + uint64_t GetCookie() const { + return m_cookie; + } + Rc GetBuffer() const { return m_buffer; } @@ -183,6 +187,8 @@ namespace dxvk { D3D11_COMMON_BUFFER_MAP_MODE m_mapMode; Rc m_buffer; + uint64_t m_cookie = 0u; + Rc m_soCounter; Rc m_sparseAllocator; uint64_t m_seq = 0ull; diff --git a/src/d3d11/d3d11_context_def.cpp b/src/d3d11/d3d11_context_def.cpp index 19db6052f..fab12b08f 100644 --- a/src/d3d11/d3d11_context_def.cpp +++ b/src/d3d11/d3d11_context_def.cpp @@ -216,23 +216,24 @@ namespace dxvk { } else if (likely(MapType == D3D11_MAP_WRITE_NO_OVERWRITE)) { // The resource must be mapped with D3D11_MAP_WRITE_DISCARD // before it can be mapped with D3D11_MAP_WRITE_NO_OVERWRITE. - auto entry = FindMapEntry(pResource, Subresource); - - if (unlikely(!entry)) { + D3D11_RESOURCE_DIMENSION resourceDim; + pResource->GetType(&resourceDim); + + if (likely(resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER)) { + D3D11_MAPPED_SUBRESOURCE sr = FindMapEntry(static_cast(pResource)->GetCookie()); + pMappedResource->pData = sr.pData; + + if (unlikely(!sr.pData)) + return D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD; + + pMappedResource->RowPitch = sr.RowPitch; + pMappedResource->DepthPitch = sr.DepthPitch; + return S_OK; + } else { + // Images cannot be mapped with NO_OVERWRITE pMappedResource->pData = nullptr; - - // NO_OVERWRITE is only supported on buffers - D3D11_RESOURCE_DIMENSION resourceDim; - pResource->GetType(&resourceDim); - - return resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER - ? D3D11_ERROR_DEFERRED_CONTEXT_MAP_WITHOUT_INITIAL_DISCARD - : E_INVALIDARG; + return E_INVALIDARG; } - - // Return same memory region as earlier - *pMappedResource = entry->MapInfo; - return S_OK; } else { // Not allowed on deferred contexts pMappedResource->pData = nullptr; @@ -281,7 +282,7 @@ namespace dxvk { ctx->invalidateBuffer(cDstBuffer, Rc(cDstSlice)); }); - AddMapEntry(pResource, 0, D3D11_RESOURCE_DIMENSION_BUFFER, *pMappedResource); + AddMapEntry(pBuffer->GetCookie(), *pMappedResource); return S_OK; } @@ -349,19 +350,15 @@ namespace dxvk { UINT CopyFlags) { void* mapPtr = nullptr; - if (unlikely(CopyFlags == D3D11_COPY_NO_OVERWRITE)) { - auto entry = FindMapEntry(pDstBuffer, 0); - - if (entry) - mapPtr = entry->MapInfo.pData; - } + if (unlikely(CopyFlags == D3D11_COPY_NO_OVERWRITE)) + mapPtr = FindMapEntry(pDstBuffer->GetCookie()).pData; if (likely(!mapPtr)) { // The caller validates the map mode, so we can // safely ignore the MapBuffer return value here D3D11_MAPPED_SUBRESOURCE mapInfo; MapBuffer(pDstBuffer, &mapInfo); - AddMapEntry(pDstBuffer, 0, D3D11_RESOURCE_DIMENSION_BUFFER, mapInfo); + AddMapEntry(pDstBuffer->GetCookie(), mapInfo); mapPtr = mapInfo.pData; } @@ -416,32 +413,27 @@ namespace dxvk { } - D3D11DeferredContextMapEntry* D3D11DeferredContext::FindMapEntry( - ID3D11Resource* pResource, - UINT Subresource) { + D3D11_MAPPED_SUBRESOURCE D3D11DeferredContext::FindMapEntry( + uint64_t Cookie) { // Recently mapped resources as well as entries with // up-to-date map infos will be located at the end // of the resource array, so scan in reverse order. size_t size = m_mappedResources.size(); for (size_t i = 1; i <= size; i++) { - auto entry = &m_mappedResources[size - i]; + const auto& entry = m_mappedResources[size - i]; - if (entry->Resource.Get() == pResource - && entry->Resource.GetSubresource() == Subresource) - return entry; + if (entry.ResourceCookie == Cookie) + return entry.MapInfo; } - return nullptr; + return D3D11_MAPPED_SUBRESOURCE(); } void D3D11DeferredContext::AddMapEntry( - ID3D11Resource* pResource, - UINT Subresource, - D3D11_RESOURCE_DIMENSION ResourceType, + uint64_t Cookie, const D3D11_MAPPED_SUBRESOURCE& MapInfo) { - m_mappedResources.emplace_back(pResource, - Subresource, ResourceType, MapInfo); + m_mappedResources.push_back({ Cookie, MapInfo }); } diff --git a/src/d3d11/d3d11_context_def.h b/src/d3d11/d3d11_context_def.h index 7f1c4eee9..1b7755514 100644 --- a/src/d3d11/d3d11_context_def.h +++ b/src/d3d11/d3d11_context_def.h @@ -8,17 +8,8 @@ namespace dxvk { struct D3D11DeferredContextMapEntry { - D3D11DeferredContextMapEntry() { } - D3D11DeferredContextMapEntry( - ID3D11Resource* pResource, - UINT Subresource, - D3D11_RESOURCE_DIMENSION ResourceType, - const D3D11_MAPPED_SUBRESOURCE& MappedResource) - : Resource(pResource, Subresource, ResourceType), - MapInfo(MappedResource) { } - - D3D11ResourceRef Resource; - D3D11_MAPPED_SUBRESOURCE MapInfo; + uint64_t ResourceCookie = 0u; + D3D11_MAPPED_SUBRESOURCE MapInfo = { }; }; class D3D11DeferredContext : public D3D11CommonContext { @@ -130,14 +121,11 @@ namespace dxvk { void TrackBufferSequenceNumber( D3D11Buffer* pResource); - D3D11DeferredContextMapEntry* FindMapEntry( - ID3D11Resource* pResource, - UINT Subresource); + D3D11_MAPPED_SUBRESOURCE FindMapEntry( + uint64_t Coookie); void AddMapEntry( - ID3D11Resource* pResource, - UINT Subresource, - D3D11_RESOURCE_DIMENSION ResourceType, + uint64_t Cookie, const D3D11_MAPPED_SUBRESOURCE& MapInfo); static DxvkCsChunkFlags GetCsChunkFlags(