mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-21 13:54:18 +01:00
[d3d11] Always use fast MAP_WRITE_DISCARD path on deferred contexts
... but keep the SingleUse option as-is anyway because games do not release their command lists after submission and end up wasting massive amounts of memory.
This commit is contained in:
parent
39f50999a3
commit
5e5c283149
@ -154,9 +154,11 @@
|
||||
# dxvk.tearFree = Auto
|
||||
|
||||
|
||||
# Assume single-use mode for command lists created on deferred contexts.
|
||||
# This may need to be disabled for some applications to avoid rendering
|
||||
# issues, which may come at a significant performance cost.
|
||||
# Assume that command lists created from deferred contexts are only used
|
||||
# once. This is extremely common and may improve performance while reducing
|
||||
# the amount of memory wasted if games keep their command list objects alive
|
||||
# for too long, but may also lead to rendering issues if command lists are
|
||||
# submitted multiple times.
|
||||
#
|
||||
# Supported values: True, False
|
||||
|
||||
|
@ -265,44 +265,24 @@ namespace dxvk {
|
||||
ID3D11Resource* pResource,
|
||||
D3D11_MAPPED_SUBRESOURCE* pMappedResource) {
|
||||
D3D11Buffer* pBuffer = static_cast<D3D11Buffer*>(pResource);
|
||||
|
||||
|
||||
if (unlikely(pBuffer->GetMapMode() == D3D11_COMMON_BUFFER_MAP_MODE_NONE)) {
|
||||
Logger::err("D3D11: Cannot map a device-local buffer");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
|
||||
auto bufferSlice = pBuffer->AllocSlice(&m_allocationCache);
|
||||
pMappedResource->pData = bufferSlice->mapPtr();
|
||||
pMappedResource->RowPitch = pBuffer->Desc()->ByteWidth;
|
||||
pMappedResource->DepthPitch = pBuffer->Desc()->ByteWidth;
|
||||
|
||||
if (likely(m_csFlags.test(DxvkCsChunkFlag::SingleUse))) {
|
||||
// For resources that cannot be written by the GPU,
|
||||
// we may write to the buffer resource directly and
|
||||
// just swap in the buffer slice as needed.
|
||||
auto bufferSlice = pBuffer->AllocSlice(&m_allocationCache);
|
||||
pMappedResource->pData = bufferSlice->mapPtr();
|
||||
|
||||
EmitCs([
|
||||
cDstBuffer = pBuffer->GetBuffer(),
|
||||
cDstSlice = std::move(bufferSlice)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cDstBuffer, Rc<DxvkResourceAllocation>(cDstSlice));
|
||||
});
|
||||
} else {
|
||||
// For GPU-writable resources, we need a data slice
|
||||
// to perform the update operation at execution time.
|
||||
auto dataSlice = AllocUpdateBufferSlice(pBuffer->Desc()->ByteWidth);
|
||||
pMappedResource->pData = dataSlice.ptr();
|
||||
EmitCs([
|
||||
cDstBuffer = pBuffer->GetBuffer(),
|
||||
cDstSlice = std::move(bufferSlice)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->invalidateBuffer(cDstBuffer, Rc<DxvkResourceAllocation>(cDstSlice));
|
||||
});
|
||||
|
||||
EmitCs([
|
||||
cDstBuffer = pBuffer->GetBuffer(),
|
||||
cDataSlice = dataSlice
|
||||
] (DxvkContext* ctx) {
|
||||
Rc<DxvkResourceAllocation> slice = cDstBuffer->allocateSlice();
|
||||
std::memcpy(slice->mapPtr(), cDataSlice.ptr(), cDataSlice.length());
|
||||
ctx->invalidateBuffer(cDstBuffer, std::move(slice));
|
||||
});
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user