rasterizer_cache: Fix surface validation

* Sometimes the copy interval might be larger than the validation interval
This commit is contained in:
GPUCode
2023-02-16 15:49:23 +02:00
parent 4bff44c9a9
commit 004b83c978

View File

@ -796,8 +796,8 @@ void RasterizerCache<T>::ValidateSurface(const Surface& surface, PAddr addr, u32
return; return;
} }
const SurfaceInterval validate_interval(addr, addr + size); const auto validate_interval = SurfaceInterval(addr, addr + size);
const SurfaceRegions validate_regions = surface->invalid_regions & validate_interval; const auto validate_regions = surface->invalid_regions & validate_interval;
if (validate_regions.empty()) { if (validate_regions.empty()) {
return; return;
} }
@ -810,6 +810,12 @@ void RasterizerCache<T>::ValidateSurface(const Surface& surface, PAddr addr, u32
for (u32 level = surface->LevelOf(addr); level <= surface->LevelOf(addr + size); level++) { for (u32 level = surface->LevelOf(addr); level <= surface->LevelOf(addr + size); level++) {
auto level_regions = validate_regions & surface->LevelInterval(level); auto level_regions = validate_regions & surface->LevelInterval(level);
const auto NotifyValidated = [&](SurfaceInterval interval) {
level_regions.erase(interval);
surface->invalid_regions.erase(interval);
};
while (!level_regions.empty()) { while (!level_regions.empty()) {
const SurfaceInterval interval = *level_regions.begin(); const SurfaceInterval interval = *level_regions.begin();
const SurfaceParams params = surface->FromInterval(interval); const SurfaceParams params = surface->FromInterval(interval);
@ -819,14 +825,14 @@ void RasterizerCache<T>::ValidateSurface(const Surface& surface, PAddr addr, u32
if (copy_surface) { if (copy_surface) {
const SurfaceInterval copy_interval = copy_surface->GetCopyableInterval(params); const SurfaceInterval copy_interval = copy_surface->GetCopyableInterval(params);
CopySurface(copy_surface, surface, copy_interval); CopySurface(copy_surface, surface, copy_interval);
level_regions.erase(copy_interval); NotifyValidated(copy_interval);
continue; continue;
} }
// Try to find surface in cache with different format // Try to find surface in cache with different format
// that can can be reinterpreted to the requested format. // that can can be reinterpreted to the requested format.
if (ValidateByReinterpretation(surface, params, interval)) { if (ValidateByReinterpretation(surface, params, interval)) {
level_regions.erase(interval); NotifyValidated(interval);
continue; continue;
} }
// Could not find a matching reinterpreter, check if we need to implement a // Could not find a matching reinterpreter, check if we need to implement a
@ -847,11 +853,9 @@ void RasterizerCache<T>::ValidateSurface(const Surface& surface, PAddr addr, u32
// Load data from 3DS memory // Load data from 3DS memory
FlushRegion(params.addr, params.size); FlushRegion(params.addr, params.size);
UploadSurface(surface, interval); UploadSurface(surface, interval);
level_regions.erase(params.GetInterval()); NotifyValidated(params.GetInterval());
} }
} }
surface->invalid_regions.erase(validate_interval);
} }
template <class T> template <class T>