From 8a9757046eaec8b0464dcc894f92125827731392 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Tue, 28 Oct 2025 09:44:48 -0400 Subject: [PATCH] Fix memory errors in buffer_cache --- src/video_core/buffer_cache/buffer_cache.h | 25 ++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index ddd940c6d2..178b62e8b1 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1568,20 +1568,37 @@ void BufferCache

::ImmediateUploadMemory([[maybe_unused]] Buffer& buffer, } template -void BufferCache

::MappedUploadMemory([[maybe_unused]] Buffer& buffer, - [[maybe_unused]] u64 total_size_bytes, - [[maybe_unused]] std::span copies) { +void BufferCache

::MappedUploadMemory(Buffer& buffer, + u64 total_size_bytes, + std::span copies) { if constexpr (USE_MEMORY_MAPS) { auto upload_staging = runtime.UploadStagingBuffer(total_size_bytes); const std::span staging_pointer = upload_staging.mapped_span; + + if (staging_pointer.size() < total_size_bytes) { + LOG_DEBUG(HW_GPU, "Staging buffer too small for total size bytes"); + return; + } + for (BufferCopy& copy : copies) { + if (copy.src_offset + copy.size > staging_pointer.size()) { + LOG_ERROR(HW_GPU, "Copy exceeds staging buffer bounds (src_offset: {}, size: {})", copy.src_offset, copy.size); + return; + } + u8* const src_pointer = staging_pointer.data() + copy.src_offset; + + if (copy.dst_offset + copy.size > buffer.Size()) { + LOG_ERROR(HW_GPU, "Copy exceeds buffer bounds (dst_offset: {}, size: {})", copy.dst_offset, copy.size); + return; + } + const DAddr device_addr = buffer.CpuAddr() + copy.dst_offset; device_memory.ReadBlockUnsafe(device_addr, src_pointer, copy.size); - // Apply the staging offset copy.src_offset += upload_staging.offset; } + const bool can_reorder = runtime.CanReorderUpload(buffer, copies); runtime.CopyBuffer(buffer, upload_staging.buffer, copies, true, can_reorder); }