mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[d3d11] Update resources mapped on deferred contexts in Map()
Apparently it is legal to use mapped buffers on deferred contexts in D3D11, so we have to execute our update code immediately. Fixes #1160.
This commit is contained in:
parent
d579f07238
commit
4cce07ccd9
@ -140,22 +140,7 @@ namespace dxvk {
|
|||||||
void STDMETHODCALLTYPE D3D11DeferredContext::Unmap(
|
void STDMETHODCALLTYPE D3D11DeferredContext::Unmap(
|
||||||
ID3D11Resource* pResource,
|
ID3D11Resource* pResource,
|
||||||
UINT Subresource) {
|
UINT Subresource) {
|
||||||
D3D10DeviceLock lock = LockContext();
|
// No-op, updates are committed in Map
|
||||||
|
|
||||||
auto entry = FindMapEntry(pResource, Subresource);
|
|
||||||
if (unlikely(entry == m_mappedResources.rend())) {
|
|
||||||
Logger::err("D3D11DeferredContext::Unmap: Subresource not mapped");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->MapType == D3D11_MAP_WRITE_DISCARD) {
|
|
||||||
D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN;
|
|
||||||
pResource->GetType(&resourceDim);
|
|
||||||
|
|
||||||
(resourceDim == D3D11_RESOURCE_DIMENSION_BUFFER)
|
|
||||||
? UnmapBuffer(pResource, &(*entry))
|
|
||||||
: UnmapImage (pResource, Subresource, &(*entry));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,11 +175,27 @@ namespace dxvk {
|
|||||||
// just swap in the buffer slice as needed.
|
// just swap in the buffer slice as needed.
|
||||||
pMapEntry->BufferSlice = pBuffer->AllocSlice();
|
pMapEntry->BufferSlice = pBuffer->AllocSlice();
|
||||||
pMapEntry->MapPointer = pMapEntry->BufferSlice.mapPtr;
|
pMapEntry->MapPointer = pMapEntry->BufferSlice.mapPtr;
|
||||||
|
|
||||||
|
EmitCs([
|
||||||
|
cDstBuffer = pBuffer->GetBuffer(),
|
||||||
|
cPhysSlice = pMapEntry->BufferSlice
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
ctx->invalidateBuffer(cDstBuffer, cPhysSlice);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// 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.
|
||||||
pMapEntry->DataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
|
pMapEntry->DataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
|
||||||
pMapEntry->MapPointer = pMapEntry->DataSlice.ptr();
|
pMapEntry->MapPointer = pMapEntry->DataSlice.ptr();
|
||||||
|
|
||||||
|
EmitCs([
|
||||||
|
cDstBuffer = pBuffer->GetBuffer(),
|
||||||
|
cDataSlice = pMapEntry->DataSlice
|
||||||
|
] (DxvkContext* ctx) {
|
||||||
|
DxvkBufferSliceHandle slice = cDstBuffer->allocSlice();
|
||||||
|
std::memcpy(slice.mapPtr, cDataSlice.ptr(), cDataSlice.length());
|
||||||
|
ctx->invalidateBuffer(cDstBuffer, slice);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -241,42 +242,6 @@ namespace dxvk {
|
|||||||
pMapEntry->DepthPitch = ySize;
|
pMapEntry->DepthPitch = ySize;
|
||||||
pMapEntry->DataSlice = AllocUpdateBufferSlice(zSize);
|
pMapEntry->DataSlice = AllocUpdateBufferSlice(zSize);
|
||||||
pMapEntry->MapPointer = pMapEntry->DataSlice.ptr();
|
pMapEntry->MapPointer = pMapEntry->DataSlice.ptr();
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void D3D11DeferredContext::UnmapBuffer(
|
|
||||||
ID3D11Resource* pResource,
|
|
||||||
const D3D11DeferredContextMapEntry* pMapEntry) {
|
|
||||||
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
|
||||||
|
|
||||||
if (likely(pBuffer->Desc()->Usage == D3D11_USAGE_DYNAMIC && m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
|
|
||||||
EmitCs([
|
|
||||||
cDstBuffer = pBuffer->GetBuffer(),
|
|
||||||
cPhysSlice = pMapEntry->BufferSlice
|
|
||||||
] (DxvkContext* ctx) {
|
|
||||||
ctx->invalidateBuffer(cDstBuffer, cPhysSlice);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
EmitCs([
|
|
||||||
cDstBuffer = pBuffer->GetBuffer(),
|
|
||||||
cDataSlice = pMapEntry->DataSlice
|
|
||||||
] (DxvkContext* ctx) {
|
|
||||||
DxvkBufferSliceHandle slice = cDstBuffer->allocSlice();
|
|
||||||
std::memcpy(slice.mapPtr, cDataSlice.ptr(), cDataSlice.length());
|
|
||||||
ctx->invalidateBuffer(cDstBuffer, slice);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void D3D11DeferredContext::UnmapImage(
|
|
||||||
ID3D11Resource* pResource,
|
|
||||||
UINT Subresource,
|
|
||||||
const D3D11DeferredContextMapEntry* pMapEntry) {
|
|
||||||
// TODO If the texture itself is mapped to host-visible
|
|
||||||
// memory, write the data slice directly to the image.
|
|
||||||
const D3D11CommonTexture* pTexture = GetCommonTexture(pResource);
|
|
||||||
|
|
||||||
EmitCs([
|
EmitCs([
|
||||||
cImage = pTexture->GetImage(),
|
cImage = pTexture->GetImage(),
|
||||||
@ -315,6 +280,8 @@ namespace dxvk {
|
|||||||
cPackedFormat);
|
cPackedFormat);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,15 +90,6 @@ namespace dxvk {
|
|||||||
UINT MapFlags,
|
UINT MapFlags,
|
||||||
D3D11DeferredContextMapEntry* pMapEntry);
|
D3D11DeferredContextMapEntry* pMapEntry);
|
||||||
|
|
||||||
void UnmapBuffer(
|
|
||||||
ID3D11Resource* pResource,
|
|
||||||
const D3D11DeferredContextMapEntry* pMapEntry);
|
|
||||||
|
|
||||||
void UnmapImage(
|
|
||||||
ID3D11Resource* pResource,
|
|
||||||
UINT Subresource,
|
|
||||||
const D3D11DeferredContextMapEntry* pMapEntry);
|
|
||||||
|
|
||||||
Com<D3D11CommandList> CreateCommandList();
|
Com<D3D11CommandList> CreateCommandList();
|
||||||
|
|
||||||
void EmitCsChunk(DxvkCsChunkRef&& chunk);
|
void EmitCsChunk(DxvkCsChunkRef&& chunk);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user