From 80250f47e9a6a8038ce1fa5077a75ab499f9094f Mon Sep 17 00:00:00 2001 From: mimimi085181 Date: Mon, 29 Feb 2016 01:42:30 +0100 Subject: [PATCH 1/2] Partial texture updates with parts of efb copies new version --- Source/Core/VideoCommon/TextureCacheBase.cpp | 39 ++++++++++++-------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index eb4b041c187f..746b7b459c2b 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -307,28 +307,35 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::DoPartialTextureUpdates(Tex TCacheEntryBase* entry = iter->second; if (entry != entry_to_update && entry->IsEfbCopy() - && entry_to_update->addr <= entry->addr - && entry->addr + entry->size_in_bytes <= entry_to_update->addr + entry_to_update->size_in_bytes + && entry->OverlapsMemoryRange(entry_to_update->addr, entry_to_update->size_in_bytes) && entry->frameCount == FRAMECOUNT_INVALID && entry->memory_stride == numBlocksX * block_size) { if (entry->hash == entry->CalculateHash()) { - u32 block_offset = (entry->addr - entry_to_update->addr) / block_size; - u32 block_x = block_offset % numBlocksX; - u32 block_y = block_offset / numBlocksX; - - u32 dst_x = block_x * block_width; - u32 dst_y = block_y * block_height; - u32 src_x = 0; - u32 src_y = 0; - - // If the EFB copy doesn't fully fit, cancel the copy process - if (entry->native_width - src_x > entry_to_update->native_width - dst_x - || entry->native_height - src_y > entry_to_update->native_height - dst_y) + u32 src_x, src_y, dst_x, dst_y; + + // Note for understanding the math: + // Normal textures can't be strided, so the 2 missing cases with src_x > 0 don't exist + if (entry->addr >= entry_to_update->addr) + { + u32 block_offset = (entry->addr - entry_to_update->addr) / block_size; + u32 block_x = block_offset % numBlocksX; + u32 block_y = block_offset / numBlocksX; + src_x = 0; + src_y = 0; + dst_x = block_x * block_width; + dst_y = block_y * block_height; + } + else { - iter++; - continue; + u32 block_offset = (entry_to_update->addr - entry->addr) / block_size; + u32 block_x = (~block_offset + 1) % numBlocksX; + u32 block_y = (block_offset + block_x) / numBlocksX; + src_x = 0; + src_y = block_y * block_height; + dst_x = block_x * block_width; + dst_y = 0; } u32 copy_width = std::min(entry->native_width - src_x, entry_to_update->native_width - dst_x); From e4f984d5dd10782ffdac07a932e78a5c22875bcd Mon Sep 17 00:00:00 2001 From: mimimi085181 Date: Wed, 16 Mar 2016 22:03:24 +0100 Subject: [PATCH 2/2] Minor fixes to the partial updates code - remove an outdated comment about the efb to ram and scaled efb restriction - when upscaling efb copies, mark the new texture as efb copy - dx12 fixes for the src box, especially the number of layers for 3D --- .../Core/VideoBackends/D3D12/TextureCache.cpp | 21 +++++++------------ Source/Core/VideoCommon/TextureCacheBase.cpp | 3 +-- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/Source/Core/VideoBackends/D3D12/TextureCache.cpp b/Source/Core/VideoBackends/D3D12/TextureCache.cpp index 309e62c6fc75..f4a57eb3e1d7 100644 --- a/Source/Core/VideoBackends/D3D12/TextureCache.cpp +++ b/Source/Core/VideoBackends/D3D12/TextureCache.cpp @@ -106,18 +106,13 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture( if (src_rect.GetWidth() == dst_rect.GetWidth() && src_rect.GetHeight() == dst_rect.GetHeight()) { - const D3D12_BOX* src_box_pointer = nullptr; - D3D12_BOX src_box; - if (src_rect.left != 0 || src_rect.top != 0) - { - src_box.front = 0; - src_box.back = 1; - src_box.left = src_rect.left; - src_box.top = src_rect.top; - src_box.right = src_rect.right; - src_box.bottom = src_rect.bottom; - src_box_pointer = &src_box; - } + D3D12_BOX srcbox; + srcbox.left = src_rect.left; + srcbox.top = src_rect.top; + srcbox.right = src_rect.right; + srcbox.bottom = src_rect.bottom; + srcbox.front = 0; + srcbox.back = srcentry->config.layers; if (static_cast(src_rect.GetHeight()) > config.height || static_cast(src_rect.GetWidth()) > config.width) @@ -137,7 +132,7 @@ void TextureCache::TCacheEntry::CopyRectangleFromTexture( m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_DEST); srcentry->m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_COPY_SOURCE); - D3D::current_command_list->CopyTextureRegion(&dst_location, dst_rect.left, dst_rect.top, 0, &src_location, src_box_pointer); + D3D::current_command_list->CopyTextureRegion(&dst_location, dst_rect.left, dst_rect.top, 0, &src_location, &srcbox); m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); srcentry->m_texture->TransitionToResourceState(D3D::current_command_list, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 746b7b459c2b..ffa2c68ad39d 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -236,7 +236,7 @@ void TextureCacheBase::ScaleTextureCacheEntryTo(TextureCacheBase::TCacheEntryBas newentry->SetDimensions((*entry)->native_width, (*entry)->native_height, 1); newentry->SetHashes((*entry)->base_hash, (*entry)->hash); newentry->frameCount = frameCount; - newentry->is_efb_copy = false; + newentry->is_efb_copy = (*entry)->is_efb_copy; MathUtil::Rectangle srcrect, dstrect; srcrect.left = 0; srcrect.top = 0; @@ -289,7 +289,6 @@ TextureCacheBase::TCacheEntryBase* TextureCacheBase::DoPartialTextureUpdates(Tex // Efb copies and paletted textures are excluded from these updates, until there's an example where a game would // benefit from this. Both would require more work to be done. - // TODO: Implement upscaling support for normal textures, and then remove the efb to ram and the scaled efb restrictions if (entry_to_update->IsEfbCopy() || isPaletteTexture) return entry_to_update;