diff options
Diffstat (limited to 'src/video_core')
| -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 06fd40851..20faa65da 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -366,7 +366,8 @@ private: | |||
| 366 | 366 | ||
| 367 | void NotifyBufferDeletion(); | 367 | void NotifyBufferDeletion(); |
| 368 | 368 | ||
| 369 | [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, bool is_written = false) const; | 369 | [[nodiscard]] Binding StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index, |
| 370 | bool is_written = false) const; | ||
| 370 | 371 | ||
| 371 | [[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size, | 372 | [[nodiscard]] TextureBufferBinding GetTextureBufferBinding(GPUVAddr gpu_addr, u32 size, |
| 372 | PixelFormat format); | 373 | PixelFormat format); |
| @@ -749,7 +750,7 @@ void BufferCache<P>::BindGraphicsStorageBuffer(size_t stage, size_t ssbo_index, | |||
| 749 | 750 | ||
| 750 | const auto& cbufs = maxwell3d->state.shader_stages[stage]; | 751 | const auto& cbufs = maxwell3d->state.shader_stages[stage]; |
| 751 | const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset; | 752 | const GPUVAddr ssbo_addr = cbufs.const_buffers[cbuf_index].address + cbuf_offset; |
| 752 | storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, is_written); | 753 | storage_buffers[stage][ssbo_index] = StorageBufferBinding(ssbo_addr, cbuf_index, is_written); |
| 753 | } | 754 | } |
| 754 | 755 | ||
| 755 | template <class P> | 756 | template <class P> |
| @@ -789,7 +790,7 @@ void BufferCache<P>::BindComputeStorageBuffer(size_t ssbo_index, u32 cbuf_index, | |||
| 789 | 790 | ||
| 790 | const auto& cbufs = launch_desc.const_buffer_config; | 791 | const auto& cbufs = launch_desc.const_buffer_config; |
| 791 | const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset; | 792 | const GPUVAddr ssbo_addr = cbufs[cbuf_index].Address() + cbuf_offset; |
| 792 | compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, is_written); | 793 | compute_storage_buffers[ssbo_index] = StorageBufferBinding(ssbo_addr, cbuf_index, is_written); |
| 793 | } | 794 | } |
| 794 | 795 | ||
| 795 | template <class P> | 796 | template <class P> |
| @@ -1935,11 +1936,26 @@ void BufferCache<P>::NotifyBufferDeletion() { | |||
| 1935 | 1936 | ||
| 1936 | template <class P> | 1937 | template <class P> |
| 1937 | typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, | 1938 | typename BufferCache<P>::Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, |
| 1939 | u32 cbuf_index, | ||
| 1938 | bool is_written) const { | 1940 | bool is_written) const { |
| 1939 | const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); | 1941 | const GPUVAddr gpu_addr = gpu_memory->Read<u64>(ssbo_addr); |
| 1940 | const u32 size = gpu_memory->Read<u32>(ssbo_addr + 8); | 1942 | const auto size = [&]() { |
| 1943 | const bool is_nvn_cbuf = cbuf_index == 0; | ||
| 1944 | // The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. | ||
| 1945 | if (is_nvn_cbuf) { | ||
| 1946 | return gpu_memory->Read<u32>(ssbo_addr + 8); | ||
| 1947 | } | ||
| 1948 | // Other titles (notably Doom Eternal) may use STG/LDG on buffer addresses in custom defined | ||
| 1949 | // cbufs, which do not store the sizes adjacent to the addresses, so use the fully | ||
| 1950 | // mapped buffer size for now. | ||
| 1951 | const u32 memory_layout_size = static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr)); | ||
| 1952 | LOG_INFO(HW_GPU, "Binding storage buffer for cbuf index {}, MemoryLayoutSize 0x{:X}", | ||
| 1953 | cbuf_index, memory_layout_size); | ||
| 1954 | return memory_layout_size; | ||
| 1955 | }(); | ||
| 1941 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); | 1956 | const std::optional<VAddr> cpu_addr = gpu_memory->GpuToCpuAddress(gpu_addr); |
| 1942 | if (!cpu_addr || size == 0) { | 1957 | if (!cpu_addr || size == 0) { |
| 1958 | LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index); | ||
| 1943 | return NULL_BINDING; | 1959 | return NULL_BINDING; |
| 1944 | } | 1960 | } |
| 1945 | const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); | 1961 | const VAddr cpu_end = Common::AlignUp(*cpu_addr + size, Core::Memory::YUZU_PAGESIZE); |