From 0498d34d18a906a08b29b4c6c67f1703558a0ef2 Mon Sep 17 00:00:00 2001 From: James Rowe Date: Wed, 29 Nov 2017 21:09:03 -0700 Subject: [PATCH] OpenGL Cache: Ignore format reinterpretation hack Several games such as Smash will cause some regions that are cached on the gpu to be revalidated, but (seemingly) we can just ignore these cases. If the data is already found on the gpu in dirty_regions, then we validate those, and skip flushing that region from cpu. Its unknown if this breaks any games, but it does speed up many games. Additionally, it removes outlines in the pokemon games. --- .../renderer_opengl/gl_rasterizer_cache.cpp | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) 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()); } }