From 8fd495f906f03e59cdc3e68ec33d0b9b6f257427 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 27 May 2026 00:04:27 +0200 Subject: [video_core] fix std::bitset<> dirty tracker OOB, fix slightly wrong index format estimate (#4006) u8 may have been 0xff, (aka. 255), but bitset was only 255 elements, so doing bitset[255] is technically OOB additionally the max size estimate for index formats was not correct, there can be up to 256 elements with a u8 format index, not just 255 Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4006 Reviewed-by: crueter Reviewed-by: MaranBr --- src/video_core/engines/maxwell_3d.cpp | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) (limited to 'src/video_core/engines/maxwell_3d.cpp') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 9aaa99f7ff..7cf351e458 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -270,31 +270,20 @@ u32 Maxwell3D::GetMaxCurrentVertices() { size_t Maxwell3D::EstimateIndexBufferSize() { GPUVAddr start_address = regs.index_buffer.StartAddress(); GPUVAddr end_address = regs.index_buffer.EndAddress(); - static constexpr std::array max_sizes = {(std::numeric_limits::max)(), - (std::numeric_limits::max)(), - (std::numeric_limits::max)()}; - const size_t byte_size = regs.index_buffer.FormatSizeInBytes(); - const size_t log2_byte_size = Common::Log2Ceil64(byte_size); - const size_t cap{GetMaxCurrentVertices() * 4 * byte_size}; - const size_t lower_cap = - std::min(static_cast(end_address - start_address), cap); - return std::min( - memory_manager.GetMemoryLayoutSize(start_address, byte_size * max_sizes[log2_byte_size]) / - byte_size, - lower_cap); + auto const byte_size = regs.index_buffer.FormatSizeInBytes(); + auto const max_size = 1ull << (byte_size * CHAR_BIT); + auto const upper_cap = GetMaxCurrentVertices() * 4 * byte_size; + auto const lower_cap = std::min(size_t(end_address - start_address), upper_cap); + return std::min(memory_manager.GetMemoryLayoutSize(start_address, byte_size * max_size) / byte_size, lower_cap); } u32 Maxwell3D::ProcessShadowRam(u32 method, u32 argument) { // Keep track of the register value in shadow_state when requested. - const auto control = shadow_state.shadow_ram_control; - if (control == Regs::ShadowRamControl::Track || - control == Regs::ShadowRamControl::TrackWithFilter) { - shadow_state.reg_array[method] = argument; - return argument; - } - if (control == Regs::ShadowRamControl::Replay) { + auto const c = shadow_state.shadow_ram_control; + if (c == Regs::ShadowRamControl::Track || c == Regs::ShadowRamControl::TrackWithFilter) + return shadow_state.reg_array[method] = argument; + else if (c == Regs::ShadowRamControl::Replay) return shadow_state.reg_array[method]; - } return argument; } @@ -317,10 +306,8 @@ void Maxwell3D::ConsumeSinkImpl() { void Maxwell3D::ProcessDirtyRegisters(u32 method, u32 argument) { regs.reg_array[method] = argument; - - for (const auto& table : dirty.tables) { + for (auto const& table : dirty.tables) dirty.flags[table[method]] = true; - } } void Maxwell3D::ProcessMethodCall(u32 method, u32 argument, u32 nonshadow_argument, bool is_last_call) { -- cgit v1.2.3