From 8159e873319df8bf541d977a561721f983cd3b39 Mon Sep 17 00:00:00 2001 From: Robin Kertels Date: Wed, 17 Mar 2021 23:05:24 +0100 Subject: [PATCH] [d3d9] Fix some issues with dirty box handling - The dst texture in UpdateSurface must be in D3DPOOL_DEFAULT which doesn't do dirty tracking. So we don't need to call AddDirtyBox there. - Clear DirtyBox when we flush managed textures with EvictManagedOnUnlock. - Do nothing in AddDirtyBox for D3DPOOL_DEFAULT textures --- src/d3d9/d3d9_common_texture.h | 4 +++ src/d3d9/d3d9_device.cpp | 49 ++++++++++++++-------------------- 2 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/d3d9/d3d9_common_texture.h b/src/d3d9/d3d9_common_texture.h index 6096068cf..f9acf4705 100644 --- a/src/d3d9/d3d9_common_texture.h +++ b/src/d3d9/d3d9_common_texture.h @@ -376,6 +376,10 @@ namespace dxvk { || box.Back <= box.Front) return; + box.Right = std::min(box.Right, m_desc.Width); + box.Bottom = std::min(box.Bottom, m_desc.Height); + box.Back = std::min(box.Back, m_desc.Depth); + D3DBOX& dirtyBox = m_dirtyBoxes[layer]; if (dirtyBox.Left == dirtyBox.Right) { dirtyBox = box; diff --git a/src/d3d9/d3d9_device.cpp b/src/d3d9/d3d9_device.cpp index 7dd2af652..910daca25 100644 --- a/src/d3d9/d3d9_device.cpp +++ b/src/d3d9/d3d9_device.cpp @@ -652,19 +652,6 @@ namespace dxvk { if (unlikely(srcTextureInfo->Desc()->Format != dstTextureInfo->Desc()->Format)) return D3DERR_INVALIDCALL; - if (dst->GetMipLevel() == 0) { - if (pSourceRect) { - D3DBOX updateDirtyRect = { UINT(pSourceRect->left), UINT(pSourceRect->top), UINT(pSourceRect->right), UINT(pSourceRect->bottom), 0, 1 }; - if (pDestinationSurface) { - updateDirtyRect.Left = pDestPoint->x; - updateDirtyRect.Top = pDestPoint->y; - } - dstTextureInfo->AddDirtyBox(&updateDirtyRect, dst->GetFace()); - } else { - dstTextureInfo->AddDirtyBox(nullptr, dst->GetFace()); - } - } - const DxvkFormatInfo* formatInfo = imageFormatInfo(dstTextureInfo->GetFormatMapping().FormatColor); VkOffset3D srcBlockOffset = { 0u, 0u, 0u }; @@ -3979,21 +3966,6 @@ namespace dxvk { if (unlikely((Flags & (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE)) == (D3DLOCK_DISCARD | D3DLOCK_NOOVERWRITE))) Flags &= ~D3DLOCK_DISCARD; - if (!(Flags & D3DLOCK_NO_DIRTY_UPDATE) && !(Flags & D3DLOCK_READONLY)) { - if (pBox && MipLevel != 0) { - D3DBOX scaledBox = *pBox; - scaledBox.Left <<= MipLevel; - scaledBox.Right = std::min(scaledBox.Right << MipLevel, pResource->Desc()->Width); - scaledBox.Top <<= MipLevel; - scaledBox.Bottom = std::min(scaledBox.Bottom << MipLevel, pResource->Desc()->Height); - scaledBox.Back <<= MipLevel; - scaledBox.Front = std::min(scaledBox.Front << MipLevel, pResource->Desc()->Depth); - pResource->AddDirtyBox(&scaledBox, Face); - } else { - pResource->AddDirtyBox(pBox, Face); - } - } - auto& desc = *(pResource->Desc()); bool alloced = pResource->CreateBufferSubresource(Subresource); @@ -4202,6 +4174,21 @@ namespace dxvk { pResource->SetLocked(Subresource, true); + if (!(Flags & D3DLOCK_NO_DIRTY_UPDATE) && !(Flags & D3DLOCK_READONLY)) { + if (pBox && MipLevel != 0) { + D3DBOX scaledBox = *pBox; + scaledBox.Left <<= MipLevel; + scaledBox.Right = std::min(scaledBox.Right << MipLevel, pResource->Desc()->Width); + scaledBox.Top <<= MipLevel; + scaledBox.Bottom = std::min(scaledBox.Bottom << MipLevel, pResource->Desc()->Height); + scaledBox.Back <<= MipLevel; + scaledBox.Front = std::min(scaledBox.Front << MipLevel, pResource->Desc()->Depth); + pResource->AddDirtyBox(&scaledBox, Face); + } else { + pResource->AddDirtyBox(pBox, Face); + } + } + if (pResource->IsManaged() && !m_d3d9Options.evictManagedOnUnlock && !readOnly) { pResource->SetNeedsUpload(Subresource, true); @@ -4252,8 +4239,11 @@ namespace dxvk { shouldFlush &= !pResource->GetReadOnlyLocked(Subresource); shouldFlush &= !pResource->IsManaged() || m_d3d9Options.evictManagedOnUnlock; - if (shouldFlush) + if (shouldFlush) { this->FlushImage(pResource, Subresource); + if (pResource->IsManaged()) + pResource->ClearDirtyBoxes(); + } // Toss our staging buffer if we're not dynamic // and we aren't managed (for sysmem copy.) @@ -5024,6 +5014,7 @@ namespace dxvk { this->FlushImage(pResource, subresource); } + pResource->ClearDirtyBoxes(); pResource->ClearNeedsUpload(); }