Skip to content

Commit

Permalink
Merge pull request #3266 from mimimi085181/partial-updates-with-parts…
Browse files Browse the repository at this point in the history
…-of-efb-copies

Partial texture updates with parts of efb copies
  • Loading branch information
delroth committed Mar 18, 2016
2 parents 421a67d + e4f984d commit 647fec9
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 31 deletions.
21 changes: 8 additions & 13 deletions Source/Core/VideoBackends/D3D12/TextureCache.cpp
Expand Up @@ -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<u32>(src_rect.GetHeight()) > config.height ||
static_cast<u32>(src_rect.GetWidth()) > config.width)
Expand All @@ -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);
Expand Down
42 changes: 24 additions & 18 deletions Source/Core/VideoCommon/TextureCacheBase.cpp
Expand Up @@ -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<int> srcrect, dstrect;
srcrect.left = 0;
srcrect.top = 0;
Expand Down Expand Up @@ -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;
Expand All @@ -307,28 +306,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);
Expand Down

0 comments on commit 647fec9

Please sign in to comment.