mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #3266 from mimimi085181/partial-updates-with-parts-of-efb-copies
Partial texture updates with parts of efb copies
This commit is contained in:
commit
647fec92a0
@ -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)
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
@ -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 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;
|
||||
|
||||
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)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user