mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-06-04 02:57:11 +02:00
[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>
This commit is contained in:
parent
8fac95dcc0
commit
8e5419209c
1 changed files with 9 additions and 15 deletions
|
|
@ -1893,23 +1893,17 @@ Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index,
|
||||||
return NULL_BINDING;
|
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 auto size = [&]() {
|
||||||
const bool is_nvn_cbuf = cbuf_index == 0;
|
const u32 memory_layout_size =
|
||||||
if (is_nvn_cbuf) {
|
static_cast<u32>(gpu_memory->GetMemoryLayoutSize(gpu_addr));
|
||||||
// * 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 u64 next_qword = gpu_memory->Read<u64>(ssbo_addr + 8);
|
const u32 packed_size = static_cast<u32>(next_qword);
|
||||||
const u32 upper_32 = static_cast<u32>(next_qword >> 32);
|
const bool next_qword_is_size = static_cast<u32>(next_qword >> 32) == 0 &&
|
||||||
// Hardware-based detection: GPU addresses have non-zero upper bits
|
packed_size != 0 &&
|
||||||
if (upper_32 == 0) {
|
packed_size <= memory_layout_size;
|
||||||
// This is a size field, not a GPU address
|
if (next_qword_is_size) {
|
||||||
return static_cast<u32>(next_qword); // Return lower_32
|
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));
|
return (std::min)(memory_layout_size, static_cast<u32>(8_MiB));
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue