diff options
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 17 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 3 |
2 files changed, 18 insertions, 2 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 1fddc1c26..0456472fd 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1178,6 +1178,14 @@ void RasterizerCacheOpenGL::FermiCopySurface( FastCopySurface(GetSurface(src_params, true), GetSurface(dst_params, false)); } +void RasterizerCacheOpenGL::AccurateCopySurface(const Surface& src_surface, + const Surface& dst_surface) { + const auto& src_params{src_surface->GetSurfaceParams()}; + const auto& dst_params{dst_surface->GetSurfaceParams()}; + FlushRegion(src_params.addr, dst_params.size_in_bytes); + LoadSurface(dst_surface); +} + Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, const SurfaceParams& new_params) { // Verify surface is compatible for blitting @@ -1186,6 +1194,12 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, // Get a new surface with the new parameters, and blit the previous surface to it Surface new_surface{GetUncachedSurface(new_params)}; + // With use_accurate_gpu_emulation enabled, do an accurate surface copy + if (Settings::values.use_accurate_gpu_emulation) { + AccurateCopySurface(old_surface, new_surface); + return new_surface; + } + // For compatible surfaces, we can just do fast glCopyImageSubData based copy if (old_params.target == new_params.target && old_params.type == new_params.type && old_params.depth == new_params.depth && old_params.depth == 1 && @@ -1200,8 +1214,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, // reinterpreted. When use_accurate_gpu_emulation setting is enabled, perform a more accurate // surface copy, where pixels are reinterpreted as a new format (without conversion). This // code path uses OpenGL PBOs and is quite slow. - const bool is_blit{old_params.pixel_format == new_params.pixel_format || - !Settings::values.use_accurate_gpu_emulation}; + const bool is_blit{old_params.pixel_format == new_params.pixel_format}; switch (new_params.target) { case SurfaceParams::SurfaceTarget::Texture2D: diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 77d925250..7c1cb72d0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -899,6 +899,9 @@ private: /// Tries to get a reserved surface for the specified parameters Surface TryGetReservedSurface(const SurfaceParams& params); + /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data + void AccurateCopySurface(const Surface& src_surface, const Surface& dst_surface); + /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have /// previously been used. This is to prevent surfaces from being constantly created and /// destroyed when used with different surface parameters. |