mirror of
https://git.citron-emu.org/citron/emu
synced 2025-05-12 19:00:37 +01:00
video_core: Add fallback handling for failed storage buffer lookups
Implements a more robust error handling approach when storage buffer lookups fail in the buffer cache. Instead of returning a null binding, the code now: - Provides a fallback buffer with safe default values - Implements warning rate limiting to prevent log spam - Tracks warning counts per cbuf_index - Logs detailed debug information periodically This change helps prevent potential crashes when storage buffer lookups fail while still maintaining visibility into the issue through strategic logging. The fallback mechanism uses a safe static address and a reasonable buffer size (16KB) to handle cases where the normal GPU to CPU address translation fails. Also updates copyright headers to include citron Emulator Project. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
parent
ff9c61e7c7
commit
66bdd6ed27
1 changed files with 28 additions and 3 deletions
|
@ -1,4 +1,5 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
@ -6,6 +7,7 @@
|
|||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "common/range_sets.inc"
|
||||
#include "video_core/buffer_cache/buffer_cache_base.h"
|
||||
|
@ -18,7 +20,7 @@ using Core::DEVICE_PAGESIZE;
|
|||
|
||||
template <class P>
|
||||
BufferCache<P>::BufferCache(Tegra::MaxwellDeviceMemoryManager& device_memory_, Runtime& runtime_)
|
||||
: runtime{runtime_}, device_memory{device_memory_}, memory_tracker{device_memory} {
|
||||
: runtime{runtime_}, device_memory{device_memory_}, memory_tracker{device_memory}, immediate_buffer_alloc{} {
|
||||
// Ensure the first slot is used for the null buffer
|
||||
void(slot_buffers.insert(runtime, NullBufferParams{}));
|
||||
gpu_modified_ranges.Clear();
|
||||
|
@ -1719,8 +1721,31 @@ Binding BufferCache<P>::StorageBufferBinding(GPUVAddr ssbo_addr, u32 cbuf_index,
|
|||
|
||||
const std::optional<DAddr> aligned_device_addr = gpu_memory->GpuToCpuAddress(aligned_gpu_addr);
|
||||
if (!aligned_device_addr || size == 0) {
|
||||
LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}", cbuf_index);
|
||||
return NULL_BINDING;
|
||||
// Use a static counter to track and limit warnings
|
||||
static std::unordered_map<u32, u32> warning_counts;
|
||||
|
||||
// Increment the warning count for this cbuf_index
|
||||
warning_counts[cbuf_index]++;
|
||||
|
||||
// Only log the first warning for each cbuf_index
|
||||
if (warning_counts[cbuf_index] == 1) {
|
||||
LOG_WARNING(HW_GPU, "Failed to find storage buffer for cbuf index {}. Using fallback.",
|
||||
cbuf_index);
|
||||
} else if (warning_counts[cbuf_index] % 1000 == 0) {
|
||||
// Log occasional reminder warnings
|
||||
LOG_DEBUG(HW_GPU, "Still using fallback for storage buffer cbuf index {} (count: {})",
|
||||
cbuf_index, warning_counts[cbuf_index]);
|
||||
}
|
||||
|
||||
// Create a dummy binding with non-zero values to avoid potential crashes
|
||||
static DAddr safe_device_addr = 0x1000;
|
||||
static const u32 safe_size = 16 * 1024; // 16KB should be adequate for most cases
|
||||
|
||||
return Binding{
|
||||
.device_addr = safe_device_addr,
|
||||
.size = safe_size,
|
||||
.buffer_id = const_cast<BufferCache<P>*>(this)->FindBuffer(safe_device_addr, safe_size),
|
||||
};
|
||||
}
|
||||
const std::optional<DAddr> device_addr = gpu_memory->GpuToCpuAddress(gpu_addr);
|
||||
ASSERT_MSG(device_addr, "Unaligned storage buffer address not found for cbuf index {}",
|
||||
|
|
Loading…
Reference in a new issue