Преглед на файлове

gl_rasterizer_cache: Use AccurateCopySurface for use_accurate_gpu_emulation.

bunnei преди 7 години
родител
ревизия
43b9494a0f
променени са 2 файла, в които са добавени 18 реда и са изтрити 2 реда
  1. 15 2
      src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
  2. 3 0
      src/video_core/renderer_opengl/gl_rasterizer_cache.h

+ 15 - 2
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:

+ 3 - 0
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.