1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-04 16:24:29 +01:00

[d3d9] Discard mapped buffer if it's currently in use

This commit is contained in:
Robin Kertels 2020-06-10 23:00:55 +02:00 committed by Joshie
parent 5d5ec2aa77
commit 7389da29be

View File

@ -3971,7 +3971,7 @@ namespace dxvk {
physSlice = pResource->DiscardMapSlice(Subresource); physSlice = pResource->DiscardMapSlice(Subresource);
EmitCs([ EmitCs([
cImageBuffer = mappedBuffer, cImageBuffer = std::move(mappedBuffer),
cBufferSlice = physSlice cBufferSlice = physSlice
] (DxvkContext* ctx) { ] (DxvkContext* ctx) {
ctx->invalidateBuffer(cImageBuffer, cBufferSlice); ctx->invalidateBuffer(cImageBuffer, cBufferSlice);
@ -3992,7 +3992,21 @@ namespace dxvk {
if (alloced) if (alloced)
std::memset(physSlice.mapPtr, 0, physSlice.length); std::memset(physSlice.mapPtr, 0, physSlice.length);
else if (!skipWait) { else if (managed && !skipWait) {
if (!WaitForResource(mappedBuffer, D3DLOCK_DONOTWAIT)) {
// if the mapped buffer is currently being copied to image and it's small enough
// we can just avoid a stall by allocating a new slice and copying the existing contents
DxvkBufferSliceHandle oldSlice = physSlice;
physSlice = pResource->DiscardMapSlice(Subresource);
std::memcpy(physSlice.mapPtr, oldSlice.mapPtr, oldSlice.length);
EmitCs([
cImageBuffer = std::move(mappedBuffer),
cBufferSlice = physSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cImageBuffer, cBufferSlice);
});
}
} else if (!skipWait) {
if (!WaitForResource(mappedBuffer, Flags)) if (!WaitForResource(mappedBuffer, Flags))
return D3DERR_WASSTILLDRAWING; return D3DERR_WASSTILLDRAWING;
} }
@ -4314,8 +4328,22 @@ namespace dxvk {
const bool skipWait = (Flags & D3DLOCK_NOOVERWRITE) || const bool skipWait = (Flags & D3DLOCK_NOOVERWRITE) ||
quickRead || quickRead ||
(boundsCheck && !pResource->DirtyRange().Overlaps(pResource->LockRange())); (boundsCheck && !pResource->DirtyRange().Overlaps(pResource->LockRange()));
if (!skipWait) { if (!skipWait) {
if (IsPoolManaged(desc.Pool)) {
if (!WaitForResource(mappingBuffer, D3DLOCK_DONOTWAIT)) {
// if the mapped buffer is currently being copied to the primary buffer and it's small enough
// we can just avoid a stall by allocating a new slice and copying the existing contents
DxvkBufferSliceHandle oldSlice = physSlice;
physSlice = pResource->DiscardMapSlice();
std::memcpy(physSlice.mapPtr, oldSlice.mapPtr, oldSlice.length);
EmitCs([
cBuffer = std::move(mappingBuffer),
cBufferSlice = physSlice
] (DxvkContext* ctx) {
ctx->invalidateBuffer(cBuffer, cBufferSlice);
});
}
} else {
if (!(Flags & D3DLOCK_DONOTWAIT)) { if (!(Flags & D3DLOCK_DONOTWAIT)) {
pResource->SetReadLocked(false); pResource->SetReadLocked(false);
pResource->DirtyRange().Clear(); pResource->DirtyRange().Clear();
@ -4324,6 +4352,7 @@ namespace dxvk {
if (!WaitForResource(mappingBuffer, Flags)) if (!WaitForResource(mappingBuffer, Flags))
return D3DERR_WASSTILLDRAWING; return D3DERR_WASSTILLDRAWING;
} }
}
// Use map pointer from previous map operation. This // Use map pointer from previous map operation. This
// way we don't have to synchronize with the CS thread // way we don't have to synchronize with the CS thread