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:
parent
2dcdd20517
commit
c82b504e52
@ -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
|
||||||
|
@ -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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user