1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-13 16:08:50 +01:00

[d3d11] Further simplify D3D11DeferredContextMapEntry

And no longer create a strong reference to the given resource.
This commit is contained in:
Philip Rebohle 2022-02-10 14:23:53 +01:00
parent 2dcdd20517
commit c82b504e52
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
2 changed files with 80 additions and 59 deletions

View File

@ -191,45 +191,35 @@ namespace dxvk {
if (unlikely(!pResource || !pMappedResource)) if (unlikely(!pResource || !pMappedResource))
return E_INVALIDARG; return E_INVALIDARG;
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
pResource->GetType(&resourceDim);
if (MapType == D3D11_MAP_WRITE_DISCARD) { if (MapType == D3D11_MAP_WRITE_DISCARD) {
D3D11DeferredContextMapEntry entry; D3D11_RESOURCE_DIMENSION resourceDim;
pResource->GetType(&resourceDim);
D3D11_MAPPED_SUBRESOURCE mapInfo;
HRESULT status = resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER HRESULT status = resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER
? MapBuffer(pResource, &entry) ? MapBuffer(pResource, &mapInfo)
: MapImage (pResource, Subresource, &entry); : MapImage (pResource, Subresource, &mapInfo);
if (unlikely(FAILED(status))) { if (unlikely(FAILED(status))) {
*pMappedResource = D3D11_MAPPED_SUBRESOURCE(); *pMappedResource = D3D11_MAPPED_SUBRESOURCE();
return status; return status;
} }
// Fill mapped resource structure AddMapEntry(pResource, Subresource, resourceDim, mapInfo);
pMappedResource->pData = entry.MapPointer; *pMappedResource = mapInfo;
pMappedResource->RowPitch = entry.RowPitch;
pMappedResource->DepthPitch = entry.DepthPitch;
// Adding a new map entry actually overrides the
// old one in practice because the lookup function
// scans the array in reverse order
m_mappedResources.push_back(std::move(entry));
return S_OK; return S_OK;
} else if (MapType == D3D11_MAP_WRITE_NO_OVERWRITE) { } else if (MapType == D3D11_MAP_WRITE_NO_OVERWRITE) {
// The resource must be mapped with D3D11_MAP_WRITE_DISCARD // The resource must be mapped with D3D11_MAP_WRITE_DISCARD
// before it can be mapped with D3D11_MAP_WRITE_NO_OVERWRITE. // before it can be mapped with D3D11_MAP_WRITE_NO_OVERWRITE.
auto entry = FindMapEntry(pResource, Subresource); auto entry = FindMapEntry(pResource, Subresource);
if (unlikely(entry == m_mappedResources.rend())) { if (unlikely(!entry)) {
*pMappedResource = D3D11_MAPPED_SUBRESOURCE(); *pMappedResource = D3D11_MAPPED_SUBRESOURCE();
return E_INVALIDARG; return E_INVALIDARG;
} }
// Return same memory region as earlier // Return same memory region as earlier
pMappedResource->pData = entry->MapPointer; *pMappedResource = entry->MapInfo;
pMappedResource->RowPitch = entry->RowPitch;
pMappedResource->DepthPitch = entry->DepthPitch;
return S_OK; return S_OK;
} else { } else {
// Not allowed on deferred contexts // Not allowed on deferred contexts
@ -283,7 +273,7 @@ namespace dxvk {
HRESULT D3D11DeferredContext::MapBuffer( HRESULT D3D11DeferredContext::MapBuffer(
ID3D11Resource* pResource, ID3D11Resource* pResource,
D3D11DeferredContextMapEntry* pMapEntry) { D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource); D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
if (unlikely(pBuffer->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_NONE)) { if (unlikely(pBuffer->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_NONE)) {
@ -291,17 +281,15 @@ namespace dxvk {
return E_INVALIDARG; return E_INVALIDARG;
} }
pMapEntry->pResource = pResource; pMappedResource->RowPitch = pBuffer->Desc()->ByteWidth;
pMapEntry->Subresource = 0; pMappedResource->DepthPitch = pBuffer->Desc()->ByteWidth;
pMapEntry->RowPitch = pBuffer->Desc()->ByteWidth;
pMapEntry->DepthPitch = pBuffer->Desc()->ByteWidth;
if (likely(m_csFlags.test(DxvkCsChunkFlag::SingleUse))) { if (likely(m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
// For resources that cannot be written by the GPU, // For resources that cannot be written by the GPU,
// we may write to the buffer resource directly and // we may write to the buffer resource directly and
// just swap in the buffer slice as needed. // just swap in the buffer slice as needed.
auto bufferSlice = pBuffer->AllocSlice(); auto bufferSlice = pBuffer->AllocSlice();
pMapEntry->MapPointer = bufferSlice.mapPtr; pMappedResource->pData = bufferSlice.mapPtr;
EmitCs([ EmitCs([
cDstBuffer = pBuffer->GetBuffer(), cDstBuffer = pBuffer->GetBuffer(),
@ -313,7 +301,7 @@ namespace dxvk {
// For GPU-writable resources, we need a data slice // For GPU-writable resources, we need a data slice
// to perform the update operation at execution time. // to perform the update operation at execution time.
auto dataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth); auto dataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
pMapEntry->MapPointer = dataSlice.ptr(); pMappedResource->pData = dataSlice.ptr();
EmitCs([ EmitCs([
cDstBuffer = pBuffer->GetBuffer(), cDstBuffer = pBuffer->GetBuffer(),
@ -332,7 +320,7 @@ namespace dxvk {
HRESULT D3D11DeferredContext::MapImage( HRESULT D3D11DeferredContext::MapImage(
ID3D11Resource* pResource, ID3D11Resource* pResource,
UINT Subresource, UINT Subresource,
D3D11DeferredContextMapEntry* pMapEntry) { D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
D3D11CommonTexture* pTexture = GetCommonTexture(pResource); D3D11CommonTexture* pTexture = GetCommonTexture(pResource);
if (unlikely(pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) { if (unlikely(pTexture->GetMapMode() == D3D11_COMMON_TEXTURE_MAP_MODE_NONE)) {
@ -354,11 +342,9 @@ namespace dxvk {
auto layout = pTexture->GetSubresourceLayout(formatInfo->aspectMask, Subresource); auto layout = pTexture->GetSubresourceLayout(formatInfo->aspectMask, Subresource);
auto dataSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, levelExtent)); auto dataSlice = AllocStagingBuffer(util::computeImageDataSize(packedFormat, levelExtent));
pMapEntry->pResource = pResource; pMappedResource->RowPitch = layout.RowPitch;
pMapEntry->Subresource = Subresource; pMappedResource->DepthPitch = layout.DepthPitch;
pMapEntry->RowPitch = layout.RowPitch; pMappedResource->pData = dataSlice.mapPtr(0);
pMapEntry->DepthPitch = layout.DepthPitch;
pMapEntry->MapPointer = dataSlice.mapPtr(0);
UpdateImage(pTexture, &subresource, UpdateImage(pTexture, &subresource,
VkOffset3D { 0, 0, 0 }, levelExtent, VkOffset3D { 0, 0, 0 }, levelExtent,
@ -378,18 +364,17 @@ namespace dxvk {
if (unlikely(CopyFlags == D3D11_COPY_NO_OVERWRITE)) { if (unlikely(CopyFlags == D3D11_COPY_NO_OVERWRITE)) {
auto entry = FindMapEntry(pDstBuffer, 0); auto entry = FindMapEntry(pDstBuffer, 0);
if (entry != m_mappedResources.rend()) if (entry)
mapPtr = entry->MapPointer; mapPtr = entry->MapInfo.pData;
} }
if (likely(!mapPtr)) { if (likely(!mapPtr)) {
// The caller validates the map mode, so we can // The caller validates the map mode, so we can
// safely ignore the MapBuffer return value here // safely ignore the MapBuffer return value here
D3D11DeferredContextMapEntry entry; D3D11_MAPPED_SUBRESOURCE mapInfo;
MapBuffer(pDstBuffer, &entry); MapBuffer(pDstBuffer, &mapInfo);
AddMapEntry(pDstBuffer, 0, D3D11_RESOURCE_DIMENSION_BUFFER, mapInfo);
mapPtr = entry.MapPointer; mapPtr = mapInfo.pData;
m_mappedResources.push_back(std::move(entry));
} }
std::memcpy(reinterpret_cast<char*>(mapPtr) + Offset, pSrcData, Length); std::memcpy(reinterpret_cast<char*>(mapPtr) + Offset, pSrcData, Length);
@ -437,6 +422,35 @@ namespace dxvk {
} }
D3D11DeferredContextMapEntry* D3D11DeferredContext::FindMapEntry(
ID3D11Resource* pResource,
UINT Subresource) {
// 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];
if (entry->Resource.Get() == pResource
&& entry->Resource.GetSubresource() == Subresource)
return entry;
}
return nullptr;
}
void D3D11DeferredContext::AddMapEntry(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_RESOURCE_DIMENSION ResourceType,
const D3D11_MAPPED_SUBRESOURCE& MapInfo) {
m_mappedResources.emplace_back(pResource,
Subresource, ResourceType, MapInfo);
}
DxvkCsChunkFlags D3D11DeferredContext::GetCsChunkFlags( DxvkCsChunkFlags D3D11DeferredContext::GetCsChunkFlags(
D3D11Device* pDevice) { D3D11Device* pDevice) {
return pDevice->GetOptions()->dcSingleUseMode return pDevice->GetOptions()->dcSingleUseMode

View File

@ -5,17 +5,22 @@
#include "d3d11_context.h" #include "d3d11_context.h"
#include "d3d11_texture.h" #include "d3d11_texture.h"
#include <algorithm>
#include <vector> #include <vector>
namespace dxvk { namespace dxvk {
struct D3D11DeferredContextMapEntry { struct D3D11DeferredContextMapEntry {
Com<ID3D11Resource> pResource; D3D11DeferredContextMapEntry() { }
UINT Subresource; D3D11DeferredContextMapEntry(
UINT RowPitch; ID3D11Resource* pResource,
UINT DepthPitch; UINT Subresource,
void* MapPointer; D3D11_RESOURCE_DIMENSION ResourceType,
const D3D11_MAPPED_SUBRESOURCE& MappedResource)
: Resource(pResource, Subresource, ResourceType),
MapInfo(MappedResource) { }
D3D11ResourceRef Resource;
D3D11_MAPPED_SUBRESOURCE MapInfo;
}; };
class D3D11DeferredContext : public D3D11DeviceContext { class D3D11DeferredContext : public D3D11DeviceContext {
@ -114,12 +119,12 @@ namespace dxvk {
HRESULT MapBuffer( HRESULT MapBuffer(
ID3D11Resource* pResource, ID3D11Resource* pResource,
D3D11DeferredContextMapEntry* pMapEntry); D3D11_MAPPED_SUBRESOURCE* pMappedResource);
HRESULT MapImage( HRESULT MapImage(
ID3D11Resource* pResource, ID3D11Resource* pResource,
UINT Subresource, UINT Subresource,
D3D11DeferredContextMapEntry* pMapEntry); D3D11_MAPPED_SUBRESOURCE* pMappedResource);
void UpdateMappedBuffer( void UpdateMappedBuffer(
D3D11Buffer* pDstBuffer, D3D11Buffer* pDstBuffer,
@ -135,23 +140,25 @@ namespace dxvk {
void EmitCsChunk(DxvkCsChunkRef&& chunk); void EmitCsChunk(DxvkCsChunkRef&& chunk);
void TrackTextureSequenceNumber( void TrackTextureSequenceNumber(
D3D11CommonTexture* pResource, D3D11CommonTexture* pResource,
UINT Subresource); UINT Subresource);
void TrackBufferSequenceNumber( void TrackBufferSequenceNumber(
D3D11Buffer* pResource); D3D11Buffer* pResource);
D3D11DeferredContextMapEntry* FindMapEntry(
ID3D11Resource* pResource,
UINT Subresource);
void AddMapEntry(
ID3D11Resource* pResource,
UINT Subresource,
D3D11_RESOURCE_DIMENSION ResourceType,
const D3D11_MAPPED_SUBRESOURCE& MapInfo);
static DxvkCsChunkFlags GetCsChunkFlags( static DxvkCsChunkFlags GetCsChunkFlags(
D3D11Device* pDevice); D3D11Device* pDevice);
auto FindMapEntry(ID3D11Resource* pResource, UINT Subresource) {
return std::find_if(m_mappedResources.rbegin(), m_mappedResources.rend(),
[pResource, Subresource] (const D3D11DeferredContextMapEntry& entry) {
return entry.pResource == pResource
&& entry.Subresource == Subresource;
});
}
}; };
} }