aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/buffer_cache
diff options
context:
space:
mode:
authorxbzk <xbzk@eden-emu.dev>2026-06-02 03:31:59 +0200
committercrueter <crueter@eden-emu.dev>2026-06-02 03:31:59 +0200
commit8e5419209c8994359eddaa2b85395dd7d756ff89 (patch)
treecf168c6f0376141530222ae4ffc6997502f21dbe /src/video_core/buffer_cache
parent8fac95dcc06a3e24956e1abcf77ff368fd08d73b (diff)
[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 <maranbr@eden-emu.dev> Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src/video_core/buffer_cache')
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h24
1 files 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<P>::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<u64>(ssbo_addr + 8);
- const u32 upper_32 = static_cast<u32>(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<u32>(next_qword); // Return lower_32
- }
+ const u32 memory_layout_size =
+ static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr));
+ const u64 next_qword = gpu_memory->Read<u64>(ssbo_addr + 8);
+ const u32 packed_size = static_cast<u32>(next_qword);
+ const bool next_qword_is_size = static_cast<u32>(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<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr));
- // Cap at 8MB to prevent allocator overflow from misinterpreted addresses
return (std::min)(memory_layout_size, static_cast<u32>(8_MiB));
}();