From 8e5419209c8994359eddaa2b85395dd7d756ff89 Mon Sep 17 00:00:00 2001 From: xbzk Date: Tue, 2 Jun 2026 03:31:59 +0200 Subject: [PATCH] [video,buffer] rewrite storagebufferbinding size() lambda to be full data driven instead of cbuf_index based (#4041) fixes an yxzx era bug where eden assumed NVN-style packed SSBO descriptors (u64 gpu_addr followed by size) only happen in cbuf_index == 0. Mega Man Star Force Collection proves that assumption is false. It has an unbiased/global-memory SSBO descriptor in cbuf_index == 3, offsets 0x100/0x300, but the descriptor still appears to be { address, size }. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4041 Reviewed-by: MaranBr Reviewed-by: crueter --- src/video_core/buffer_cache/buffer_cache.h | 24 ++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index b36dd46176..8c36a40377 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1893,23 +1893,17 @@ Binding BufferCache

::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index, return NULL_BINDING; } - // xbzk: New size logic. Fixes MCI. - // If ever the * comment below prove wrong, the 'if' block may be removed. const auto size = [&]() { - const bool is_nvn_cbuf = cbuf_index == 0; - if (is_nvn_cbuf) { - // * The NVN driver buffer (index 0) is known to pack the SSBO address followed by its size. - const u64 next_qword = gpu_memory->Read(ssbo_addr + 8); - const u32 upper_32 = static_cast(next_qword >> 32); - // Hardware-based detection: GPU addresses have non-zero upper bits - if (upper_32 == 0) { - // This is a size field, not a GPU address - return static_cast(next_qword); // Return lower_32 - } + const u32 memory_layout_size = + static_cast(gpu_memory->GetMemoryLayoutSize(gpu_addr)); + const u64 next_qword = gpu_memory->Read(ssbo_addr + 8); + const u32 packed_size = static_cast(next_qword); + const bool next_qword_is_size = static_cast(next_qword >> 32) == 0 && + packed_size != 0 && + packed_size <= memory_layout_size; + if (next_qword_is_size) { + return packed_size; } - // Fall through: either not NVN cbuf (Doom Eternal & +), or NVN but ssbo_addr+8 is a GPU address (MCI) - const u32 memory_layout_size = static_cast(gpu_memory->GetMemoryLayoutSize(gpu_addr)); - // Cap at 8MB to prevent allocator overflow from misinterpreted addresses return (std::min)(memory_layout_size, static_cast(8_MiB)); }();