diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 30632dc0d..a75e504a8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1269,11 +1269,15 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, PAddr addr, return; } - const auto validate_regions = surface->invalid_regions.find(validate_interval); + auto validate_regions = surface->invalid_regions & validate_interval; + auto notify_validated = [&](SurfaceInterval interval) { + surface->invalid_regions.erase(interval); + validate_regions.erase(interval); + }; for (;;) { const auto it = validate_regions.begin(); - if (it == surface->invalid_regions.end()) + if (it == validate_regions.end()) break; const auto interval = *it & validate_interval; @@ -1285,15 +1289,28 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, PAddr addr, if (copy_surface != nullptr) { SurfaceInterval copy_interval = params.GetCopyableInterval(copy_surface); CopySurface(copy_surface, surface, copy_interval); - validate_regions.erase(interval); + notify_validated(copy_interval); continue; } + // HACK HACK HACK: Ignore format reinterpretation + // this is a placeholder for HW texture decoding/encoding + constexpr bool IGNORE_FORMAT_REINTERPRETING = true; + bool retry = false; + if (IGNORE_FORMAT_REINTERPRETING) { + for (const auto& pair : RangeFromInterval(dirty_regions, interval)) { + validate_regions.erase(pair.first & interval); + retry = true; + } + } + if (retry) + continue; + // Load data from 3DS memory FlushRegion(params.addr, params.size); surface->LoadGLBuffer(params.addr, params.end); surface->UploadGLTexture(surface->GetSubRect(params)); - validate_regions.erase(interval) + notify_validated(params.GetInterval()); } }