From 210c30aef9ddd44c14f20e8d178319e259b1c574 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Fri, 28 Aug 2020 23:49:23 +0300 Subject: [PATCH] [D3D12] Fix resolve not syncing with CPU memory and memory extent calculation --- src/xenia/gpu/d3d12/render_target_cache.cc | 4 +++- src/xenia/gpu/d3d12/shared_memory.h | 13 ++++++++----- src/xenia/gpu/d3d12/texture_cache.cc | 2 +- src/xenia/gpu/draw_util.cc | 3 +-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/xenia/gpu/d3d12/render_target_cache.cc b/src/xenia/gpu/d3d12/render_target_cache.cc index 35e6d5667..47c3df932 100644 --- a/src/xenia/gpu/d3d12/render_target_cache.cc +++ b/src/xenia/gpu/d3d12/render_target_cache.cc @@ -1133,7 +1133,7 @@ bool RenderTargetCache::Resolve(const Memory& memory, copy_dest_resident = texture_cache.EnsureScaledResolveBufferResident( resolve_info.copy_dest_base, resolve_info.copy_dest_length); } else { - copy_dest_resident = shared_memory.EnsureTilesResident( + copy_dest_resident = shared_memory.RequestRange( resolve_info.copy_dest_base, resolve_info.copy_dest_length); } if (copy_dest_resident) { @@ -1225,6 +1225,8 @@ bool RenderTargetCache::Resolve(const Memory& memory, written_length_out = resolve_info.copy_dest_length; copied = true; } + } else { + XELOGE("Failed to obtain the resolve destination memory region"); } } } else { diff --git a/src/xenia/gpu/d3d12/shared_memory.h b/src/xenia/gpu/d3d12/shared_memory.h index bcd1ed2cb..125245aa4 100644 --- a/src/xenia/gpu/d3d12/shared_memory.h +++ b/src/xenia/gpu/d3d12/shared_memory.h @@ -85,10 +85,6 @@ class SharedMemory { // Unregisters previously registered watched memory range. void UnwatchMemoryRange(WatchHandle handle); - // Ensures the buffer tiles backing the range are resident, but doesn't upload - // anything. - bool EnsureTilesResident(uint32_t start, uint32_t length); - // Checks if the range has been updated, uploads new data if needed and // ensures the buffer tiles backing the range are resident. May transition the // tiled buffer to copy destination - call this before UseForReading or @@ -106,7 +102,10 @@ class SharedMemory { // Marks the range as containing GPU-generated data (such as resolves), // triggering modification callbacks, making it valid (so pages are not // copied from the main memory until they're modified by the CPU) and - // protecting it. + // protecting it. Before writing anything from the GPU side, RequestRange must + // be called, to make sure, if the GPU writes don't overwrite *everything* in + // the pages they touch, the CPU data is properly loaded to the unmodified + // regions in those pages. void RangeWrittenByGPU(uint32_t start, uint32_t length); // Makes the buffer usable for vertices, indices and texture untiling. @@ -185,6 +184,10 @@ class SharedMemory { // Total buffer page count. uint32_t page_count_; + // Ensures the buffer tiles backing the range are resident, but doesn't upload + // anything. + bool EnsureTilesResident(uint32_t start, uint32_t length); + // Non-shader-visible buffer descriptor heap for faster binding (via copying // rather than creation). enum class BufferDescriptorIndex : uint32_t { diff --git a/src/xenia/gpu/d3d12/texture_cache.cc b/src/xenia/gpu/d3d12/texture_cache.cc index 204eb00ad..1b4525e4d 100644 --- a/src/xenia/gpu/d3d12/texture_cache.cc +++ b/src/xenia/gpu/d3d12/texture_cache.cc @@ -1878,7 +1878,7 @@ void TextureCache::LogTextureAction(const Texture* texture, const char* action) { XELOGGPU( "{} {} {}{}x{}x{} {} {} texture with {} {}packed mip level{}, " - "base at 0x{:08X} (size {}), mips at 0x{:08X} (size {})", + "base at 0x{:08X} (size 0x{:08X}), mips at 0x{:08X} (size 0x{:08X})", action, texture->key.tiled ? "tiled" : "linear", texture->key.scaled_resolve ? "2x-scaled " : "", texture->key.width, texture->key.height, texture->key.depth, diff --git a/src/xenia/gpu/draw_util.cc b/src/xenia/gpu/draw_util.cc index e925b59d4..718f22ea0 100644 --- a/src/xenia/gpu/draw_util.cc +++ b/src/xenia/gpu/draw_util.cc @@ -380,8 +380,7 @@ bool GetResolveInfo(const RegisterFile& regs, const Memory& memory, dest_width, dest_height, dest_depth); } copy_dest_length = texture_util::GetGuestMipSliceStorageSize( - dest_width, dest_height, dest_depth, false, dest_format, nullptr, - false); + dest_width, dest_height, dest_depth, true, dest_format, nullptr, false); } else { XELOGE("Tried to resolve to format {}, which is not a ColorFormat", dest_format_info.name);