diff options
| author | 2023-03-09 09:18:39 -0500 | |
|---|---|---|
| committer | 2023-03-09 09:18:39 -0500 | |
| commit | b5c0c1e16360ad7c3b82d70d46c2193b6e32fe63 (patch) | |
| tree | ab2ac964d3ed958f42e0dd362f746cc702bd0ebf /src/video_core/buffer_cache | |
| parent | Merge pull request #9906 from german77/metroid2 (diff) | |
| parent | buffer_cache: Add logic for non-NVN storage buffer tracking (diff) | |
| download | yuzu-b5c0c1e16360ad7c3b82d70d46c2193b6e32fe63.tar.gz yuzu-b5c0c1e16360ad7c3b82d70d46c2193b6e32fe63.tar.xz yuzu-b5c0c1e16360ad7c3b82d70d46c2193b6e32fe63.zip | |
Merge pull request #9822 from ameerj/buffcache-ssbo-addr
buffer_cache: Add logic for non-NVN storage buffer tracking
Diffstat (limited to 'src/video_core/buffer_cache')
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 2a150ccdc..1f656ffa8 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -383,7 +383,8 @@ private: | |||
| 383 | 383 | ||
| 384 | void NotifyBufferDeletion(); | 384 | void NotifyBufferDeletion(); |
| 385 | 385 | ||
| 386 | [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, bool is_written = false) const; | 386 | [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index, |
| 387 | bool is_written = false) const; | ||
| 387 | 388 | ||
| 388 | [[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size, | 389 | [[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size, |
| 389 | PixelFormat format); | 390 | PixelFormat format); |
| @@ -802,7 +803,7 @@ void BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index, | |||
| 802 | 803 | ||
| 803 | const auto& cbufs = maxwell3d->state.shader_stages[stage]; | 804 | const auto& cbufs = maxwell3d->state.shader_stages[stage]; |
| 804 | const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset; | 805 | const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset; |
| 805 | storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, is_written); | 806 | storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, cbuf_index, is_written); |
| 806 | } | 807 | } |
| 807 | 808 | ||
| 808 | template <class P> | 809 | template <class P> |
| @@ -842,7 +843,7 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, | |||
| 842 | 843 | ||
| 843 | const auto& cbufs = launch_desc.const_buffer_config; | 844 | const auto& cbufs = launch_desc.const_buffer_config; |
| 844 | const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset; | 845 | const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset; |
| 845 | compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, is_written); | 846 | compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, cbuf_index, is_written); |
| 846 | } | 847 | } |
| 847 | 848 | ||
| 848 | template <class P> | 849 | template <class P> |
| @@ -1988,11 +1989,26 @@ void BufferCache<P>::NotifyBufferDeletion() { | |||
| 1988 | 1989 | ||
| 1989 | template <class P> | 1990 | template <class P> |
| 1990 | typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, | 1991 | typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, |
| 1992 | u32 cbuf_index, | ||
| 1991 | bool is_written) const { | 1993 | bool is_written) const { |
| 1992 | const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); | 1994 | const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); |
| 1993 | const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8); | 1995 | const auto size = [&]() { |
| 1996 | const bool is_nvn_cbuf = cbuf_index == 0; | ||
| 1997 | // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. | ||
| 1998 | if (is_nvn_cbuf) { | ||
| 1999 | return gpu_memory->Read<u32>(ssbo_addr + 8); | ||
| 2000 | } | ||
| 2001 | // Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined | ||
| 2002 | // cbufs, which do not store the sizes adjacent to the addresses, so use the fully | ||
| 2003 | // mapped buffer size for now. | ||
| 2004 | const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); | ||
| 2005 | LOG_INFO(HW_GPU, "Binding storage buffer for cbuf index {}, MemoryLayoutSize 0x{:X}", | ||
| 2006 | cbuf_index, memory_layout_size); | ||
| 2007 | return memory_layout_size; | ||
| 2008 | }(); | ||
| 1994 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); | 2009 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); |
| 1995 | if (!cpu_addr || size == 0) { | 2010 | if (!cpu_addr || size == 0) { |
| 2011 | LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index); | ||
| 1996 | return NULL_BINDING; | 2012 | return NULL_BINDING; |
| 1997 | } | 2013 | } |
| 1998 | const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); | 2014 | const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); |