From 11a1442229e097ddeb092afd4f0bf444c5042b10 Mon Sep 17 00:00:00 2001
From: Frederic L <frederic.laing.development@gmail.com>
Date: Mon, 19 Nov 2018 04:53:03 +0100
Subject: [PATCH] Eliminated unnessessary memory allocation and copy (#1702)

---
 .../renderer_opengl/gl_rasterizer_cache.cpp       |  7 ++-----
 src/video_core/textures/decoders.cpp              | 15 +++++++++++----
 src/video_core/textures/decoders.h                |  7 +++++++
 3 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index b44ecfa1ca..9ca82c06cb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -381,11 +381,8 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d
     const u32 tile_size_y{GetDefaultBlockHeight(format)};
 
     if (morton_to_gl) {
-        const std::vector<u8> data =
-            Tegra::Texture::UnswizzleTexture(addr, tile_size_x, tile_size_y, bytes_per_pixel,
-                                             stride, height, depth, block_height, block_depth);
-        const std::size_t size_to_copy{std::min(gl_buffer_size, data.size())};
-        memcpy(gl_buffer, data.data(), size_to_copy);
+        Tegra::Texture::UnswizzleTexture(gl_buffer, addr, tile_size_x, tile_size_y, bytes_per_pixel,
+                                         stride, height, depth, block_height, block_depth);
     } else {
         Tegra::Texture::CopySwizzledData((stride + tile_size_x - 1) / tile_size_x,
                                          (height + tile_size_y - 1) / tile_size_y, depth,
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 19f30b1b52..c9160b467b 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -229,14 +229,21 @@ u32 BytesPerPixel(TextureFormat format) {
     }
 }
 
+void UnswizzleTexture(u8* const unswizzled_data, VAddr address, u32 tile_size_x, u32 tile_size_y,
+                      u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height,
+                      u32 block_depth) {
+    CopySwizzledData((width + tile_size_x - 1) / tile_size_x,
+                     (height + tile_size_y - 1) / tile_size_y, depth, bytes_per_pixel,
+                     bytes_per_pixel, Memory::GetPointer(address), unswizzled_data, true,
+                     block_height, block_depth);
+}
+
 std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size_x, u32 tile_size_y,
                                  u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
                                  u32 block_height, u32 block_depth) {
     std::vector<u8> unswizzled_data(width * height * depth * bytes_per_pixel);
-    CopySwizzledData((width + tile_size_x - 1) / tile_size_x,
-                     (height + tile_size_y - 1) / tile_size_y, depth, bytes_per_pixel,
-                     bytes_per_pixel, Memory::GetPointer(address), unswizzled_data.data(), true,
-                     block_height, block_depth);
+    UnswizzleTexture(unswizzled_data.data(), address, tile_size_x, tile_size_y, bytes_per_pixel,
+                     width, height, depth, block_height, block_depth);
     return unswizzled_data;
 }
 
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index ba065510b9..f4ef7c73eb 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -16,6 +16,13 @@ inline std::size_t GetGOBSize() {
     return 512;
 }
 
+/**
+ * Unswizzles a swizzled texture without changing its format.
+ */
+void UnswizzleTexture(u8* unswizzled_data, VAddr address, u32 tile_size_x, u32 tile_size_y,
+                      u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
+                      u32 block_height = TICEntry::DefaultBlockHeight,
+                      u32 block_depth = TICEntry::DefaultBlockHeight);
 /**
  * Unswizzles a swizzled texture without changing its format.
  */