From 1579f96397892153b3a76c5701a0a4e543619a97 Mon Sep 17 00:00:00 2001
From: emufan4568 <geoster3d@gmail.com>
Date: Sun, 21 Aug 2022 13:32:02 +0300
Subject: [PATCH] rasterizer_cache: Remove remaining OpenGL code

---
 .../rasterizer_cache/rasterizer_cache.cpp     | 98 ++++---------------
 .../renderer_opengl/gl_rasterizer.cpp         | 26 ++---
 .../renderer_opengl/gl_resource_manager.cpp   | 84 ++++++++--------
 .../renderer_opengl/gl_resource_manager.h     |  7 +-
 .../renderer_opengl/texture_downloader_es.cpp |  2 +-
 5 files changed, 77 insertions(+), 140 deletions(-)

diff --git a/src/video_core/rasterizer_cache/rasterizer_cache.cpp b/src/video_core/rasterizer_cache/rasterizer_cache.cpp
index 2a64506c1..fe7c8f841 100644
--- a/src/video_core/rasterizer_cache/rasterizer_cache.cpp
+++ b/src/video_core/rasterizer_cache/rasterizer_cache.cpp
@@ -7,13 +7,11 @@
 #include "common/alignment.h"
 #include "common/logging/log.h"
 #include "common/microprofile.h"
-#include "common/scope_exit.h"
 #include "video_core/pica_state.h"
 #include "video_core/rasterizer_cache/rasterizer_cache.h"
 #include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
 #include "video_core/renderer_opengl/texture_downloader_es.h"
 #include "video_core/renderer_opengl/gl_format_reinterpreter.h"
-#include "video_core/renderer_opengl/gl_state.h"
 #include "video_core/renderer_opengl/gl_vars.h"
 
 namespace OpenGL {
@@ -78,76 +76,24 @@ static constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
 }
 
 // Allocate an uninitialized texture of appropriate size and format for the surface
-OGLTexture RasterizerCacheOpenGL::AllocateSurfaceTexture(const FormatTuple& format_tuple, u32 width,
-                                                         u32 height) {
-    auto recycled_tex = host_texture_recycler.find({format_tuple, width, height});
+OGLTexture RasterizerCacheOpenGL::AllocateSurfaceTexture(const FormatTuple& tuple,
+                                                         u32 width, u32 height) {
+    auto recycled_tex = host_texture_recycler.find({tuple, width, height});
     if (recycled_tex != host_texture_recycler.end()) {
         OGLTexture texture = std::move(recycled_tex->second);
         host_texture_recycler.erase(recycled_tex);
         return texture;
     }
+
+    const GLsizei levels = static_cast<GLsizei>(std::log2(std::max(width, height))) + 1;
+
     OGLTexture texture;
     texture.Create();
-
-    OpenGLState cur_state = OpenGLState::GetCurState();
-    // Keep track of previous texture bindings
-    GLuint old_tex = cur_state.texture_units[0].texture_2d;
-    cur_state.texture_units[0].texture_2d = texture.handle;
-    cur_state.Apply();
-    glActiveTexture(GL_TEXTURE0);
-
-    if (GL_ARB_texture_storage) {
-        // Allocate all possible mipmap levels upfront
-        const GLsizei levels = static_cast<GLsizei>(std::log2(std::max(width, height))) + 1;
-        glTexStorage2D(GL_TEXTURE_2D, levels, format_tuple.internal_format, width, height);
-    } else {
-        glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, width, height, 0,
-                     format_tuple.format, format_tuple.type, nullptr);
-    }
-
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-    // Restore previous texture bindings
-    cur_state.texture_units[0].texture_2d = old_tex;
-    cur_state.Apply();
+    texture.Allocate(GL_TEXTURE_2D, levels, tuple.internal_format, width, height);
 
     return texture;
 }
 
-static void AllocateTextureCube(GLuint texture, const FormatTuple& format_tuple, u32 width) {
-    OpenGLState cur_state = OpenGLState::GetCurState();
-
-    // Keep track of previous texture bindings
-    GLuint old_tex = cur_state.texture_cube_unit.texture_cube;
-    cur_state.texture_cube_unit.texture_cube = texture;
-    cur_state.Apply();
-    glActiveTexture(TextureUnits::TextureCube.Enum());
-    if (GL_ARB_texture_storage) {
-        // Allocate all possible mipmap levels in case the game uses them later
-        const GLsizei levels = static_cast<GLsizei>(std::log2(width)) + 1;
-        glTexStorage2D(GL_TEXTURE_CUBE_MAP, levels, format_tuple.internal_format, width, width);
-    } else {
-        for (auto faces : {
-                 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
-                 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
-                 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
-                 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
-                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
-                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
-             }) {
-            glTexImage2D(faces, 0, format_tuple.internal_format, width, width, 0,
-                         format_tuple.format, format_tuple.type, nullptr);
-        }
-    }
-
-    // Restore previous texture bindings
-    cur_state.texture_cube_unit.texture_cube = old_tex;
-    cur_state.Apply();
-}
-
 MICROPROFILE_DEFINE(OpenGL_CopySurface, "OpenGL", "CopySurface", MP_RGB(128, 192, 64));
 void RasterizerCacheOpenGL::CopySurface(const Surface& src_surface, const Surface& dst_surface,
                                         SurfaceInterval copy_interval) {
@@ -562,20 +508,19 @@ const CachedTextureCube& RasterizerCacheOpenGL::GetTextureCube(const TextureCube
     auto& cube = texture_cube_cache[config];
 
     struct Face {
-        Face(std::shared_ptr<SurfaceWatcher>& watcher, PAddr address, GLenum gl_face)
-            : watcher(watcher), address(address), gl_face(gl_face) {}
+        Face(std::shared_ptr<SurfaceWatcher>& watcher, PAddr address)
+            : watcher(watcher), address(address) {}
         std::shared_ptr<SurfaceWatcher>& watcher;
         PAddr address;
-        GLenum gl_face;
     };
 
     const std::array<Face, 6> faces{{
-        {cube.px, config.px, GL_TEXTURE_CUBE_MAP_POSITIVE_X},
-        {cube.nx, config.nx, GL_TEXTURE_CUBE_MAP_NEGATIVE_X},
-        {cube.py, config.py, GL_TEXTURE_CUBE_MAP_POSITIVE_Y},
-        {cube.ny, config.ny, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y},
-        {cube.pz, config.pz, GL_TEXTURE_CUBE_MAP_POSITIVE_Z},
-        {cube.nz, config.nz, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z},
+        {cube.px, config.px},
+        {cube.nx, config.nx},
+        {cube.py, config.py},
+        {cube.ny, config.ny},
+        {cube.pz, config.pz},
+        {cube.nz, config.nz},
     }};
 
     for (const Face& face : faces) {
@@ -606,18 +551,17 @@ const CachedTextureCube& RasterizerCacheOpenGL::GetTextureCube(const TextureCube
             }
         }
 
+        const auto& tuple = GetFormatTuple(PixelFormatFromTextureFormat(config.format));
+        const u32 width = cube.res_scale * config.width;
+        const GLsizei levels = static_cast<GLsizei>(std::log2(width)) + 1;
+
+        // Allocate the cube texture
         cube.texture.Create();
-        AllocateTextureCube(
-            cube.texture.handle,
-            GetFormatTuple(PixelFormatFromTextureFormat(config.format)),
-            cube.res_scale * config.width);
+        cube.texture.Allocate(GL_TEXTURE_CUBE_MAP, levels, tuple.internal_format, width, width);
     }
 
     u32 scaled_size = cube.res_scale * config.width;
 
-    OpenGLState prev_state = OpenGLState::GetCurState();
-    SCOPE_EXIT({ prev_state.Apply(); });
-
     for (const Face& face : faces) {
         if (face.watcher && !face.watcher->IsValid()) {
             auto surface = face.watcher->Get();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index db667577c..64ae0c827 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -717,27 +717,21 @@ bool RasterizerOpenGL::Draw(bool accelerate, bool is_indexed) {
     }
 
     OGLTexture temp_tex;
-    if (need_duplicate_texture && (GLAD_GL_ARB_copy_image || GLES)) {
+    if (need_duplicate_texture) {
+        const auto& tuple = GetFormatTuple(color_surface->pixel_format);
+        const GLsizei levels = color_surface->max_level + 1;
+
         // The game is trying to use a surface as a texture and framebuffer at the same time
         // which causes unpredictable behavior on the host.
         // Making a copy to sample from eliminates this issue and seems to be fairly cheap.
         temp_tex.Create();
-        glBindTexture(GL_TEXTURE_2D, temp_tex.handle);
-        auto [internal_format, format, type] = GetFormatTuple(color_surface->pixel_format);
-        OGLTexture::Allocate(GL_TEXTURE_2D, color_surface->max_level + 1, internal_format, format,
-                             type, color_surface->GetScaledWidth(),
-                             color_surface->GetScaledHeight());
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-        glBindTexture(GL_TEXTURE_2D, state.texture_units[0].texture_2d);
+        temp_tex.Allocate(GL_TEXTURE_2D, levels, tuple.internal_format,
+                          color_surface->GetScaledWidth(),
+                          color_surface->GetScaledHeight());
 
-        for (u32 level{0}; level <= color_surface->max_level; ++level) {
-            glCopyImageSubData(color_surface->texture.handle, GL_TEXTURE_2D, level, 0, 0, 0,
-                               temp_tex.handle, GL_TEXTURE_2D, level, 0, 0, 0,
-                               color_surface->GetScaledWidth() >> level,
-                               color_surface->GetScaledHeight() >> level, 1);
-        }
+        temp_tex.CopyFrom(color_surface->texture, GL_TEXTURE_2D, levels,
+                          color_surface->GetScaledWidth(),
+                          color_surface->GetScaledHeight());
 
         for (auto& unit : state.texture_units) {
             if (unit.texture_2d == color_surface->texture.handle) {
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index 3c2124699..efd82804d 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -6,7 +6,6 @@
 #include "video_core/renderer_opengl/gl_resource_manager.h"
 #include "video_core/renderer_opengl/gl_shader_util.h"
 #include "video_core/renderer_opengl/gl_state.h"
-#include "video_core/renderer_opengl/gl_vars.h"
 
 MICROPROFILE_DEFINE(OpenGL_ResourceCreation, "OpenGL", "Resource Creation", MP_RGB(128, 128, 192));
 MICROPROFILE_DEFINE(OpenGL_ResourceDeletion, "OpenGL", "Resource Deletion", MP_RGB(128, 128, 192));
@@ -14,16 +13,18 @@ MICROPROFILE_DEFINE(OpenGL_ResourceDeletion, "OpenGL", "Resource Deletion", MP_R
 namespace OpenGL {
 
 void OGLRenderbuffer::Create() {
-    if (handle != 0)
+    if (handle != 0) {
         return;
+    }
 
     MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
     glGenRenderbuffers(1, &handle);
 }
 
 void OGLRenderbuffer::Release() {
-    if (handle == 0)
+    if (handle == 0) {
         return;
+    }
 
     MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
     glDeleteRenderbuffers(1, &handle);
@@ -32,16 +33,18 @@ void OGLRenderbuffer::Release() {
 }
 
 void OGLTexture::Create() {
-    if (handle != 0)
+    if (handle != 0) {
         return;
+    }
 
     MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
     glGenTextures(1, &handle);
 }
 
 void OGLTexture::Release() {
-    if (handle == 0)
+    if (handle == 0) {
         return;
+    }
 
     MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
     glDeleteTextures(1, &handle);
@@ -49,73 +52,66 @@ void OGLTexture::Release() {
     handle = 0;
 }
 
-void OGLTexture::Allocate(GLenum target, GLsizei levels, GLenum internalformat, GLenum format,
-                          GLenum type, GLsizei width, GLsizei height, GLsizei depth) {
-    const bool tex_storage = GLAD_GL_ARB_texture_storage || GLES;
+void OGLTexture::Allocate(GLenum target, GLsizei levels, GLenum internalformat,
+                          GLsizei width, GLsizei height, GLsizei depth) {
+    GLuint old_tex = OpenGLState::GetCurState().texture_units[0].texture_2d;
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, handle);
 
     switch (target) {
     case GL_TEXTURE_1D:
     case GL_TEXTURE:
-        if (tex_storage) {
-            glTexStorage1D(target, levels, internalformat, width);
-        } else {
-            for (GLsizei level{0}; level < levels; ++level) {
-                glTexImage1D(target, level, internalformat, width, 0, format, type, nullptr);
-                width >>= 1;
-            }
-        }
+        glTexStorage1D(target, levels, internalformat, width);
         break;
     case GL_TEXTURE_2D:
     case GL_TEXTURE_1D_ARRAY:
     case GL_TEXTURE_RECTANGLE:
     case GL_TEXTURE_CUBE_MAP:
-        if (tex_storage) {
-            glTexStorage2D(target, levels, internalformat, width, height);
-        } else {
-            for (GLsizei level{0}; level < levels; ++level) {
-                glTexImage2D(target, level, internalformat, width, height, 0, format, type,
-                             nullptr);
-                width >>= 1;
-                if (target != GL_TEXTURE_1D_ARRAY)
-                    height >>= 1;
-            }
-        }
+        glTexStorage2D(target, levels, internalformat, width, height);
         break;
     case GL_TEXTURE_3D:
     case GL_TEXTURE_2D_ARRAY:
     case GL_TEXTURE_CUBE_MAP_ARRAY:
-        if (tex_storage) {
-            glTexStorage3D(target, levels, internalformat, width, height, depth);
-        } else {
-            for (GLsizei level{0}; level < levels; ++level) {
-                glTexImage3D(target, level, internalformat, width, height, depth, 0, format, type,
-                             nullptr);
-
-                width >>= 1;
-                height >>= 1;
-                if (target == GL_TEXTURE_3D)
-                    depth >>= 1;
-            }
-        }
+        glTexStorage3D(target, levels, internalformat, width, height, depth);
         break;
     }
 
-    if (!tex_storage) {
-        glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels - 1);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+    glBindTexture(GL_TEXTURE_2D, old_tex);
+}
+
+void OGLTexture::CopyFrom(const OGLTexture& other, GLenum target, GLsizei levels,
+                          GLsizei width, GLsizei height) {
+    GLuint old_tex = OpenGLState::GetCurState().texture_units[0].texture_2d;
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, handle);
+
+    for (u32 level = 0; level < levels; level++) {
+        glCopyImageSubData(other.handle, target, level, 0, 0, 0,
+                           handle, target, level, 0, 0, 0,
+                           width >> level,
+                           height >> level, 1);
     }
+
+    glBindTexture(GL_TEXTURE_2D, old_tex);
 }
 
 void OGLSampler::Create() {
-    if (handle != 0)
+    if (handle != 0) {
         return;
+    }
 
     MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
     glGenSamplers(1, &handle);
 }
 
 void OGLSampler::Release() {
-    if (handle == 0)
+    if (handle == 0) {
         return;
+    }
 
     MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
     glDeleteSamplers(1, &handle);
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.h b/src/video_core/renderer_opengl/gl_resource_manager.h
index 0c306b584..9abbd1c5d 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.h
+++ b/src/video_core/renderer_opengl/gl_resource_manager.h
@@ -58,8 +58,11 @@ public:
     /// Deletes the internal OpenGL resource
     void Release();
 
-    static void Allocate(GLenum target, GLsizei levels, GLenum internalformat, GLenum format,
-                         GLenum type, GLsizei width, GLsizei height = 1, GLsizei depth = 1);
+    void Allocate(GLenum target, GLsizei levels, GLenum internalformat,
+                  GLsizei width, GLsizei height = 1, GLsizei depth = 1);
+
+    void CopyFrom(const OGLTexture& other, GLenum target, GLsizei levels,
+                  GLsizei width, GLsizei height);
 
     GLuint handle = 0;
 };
diff --git a/src/video_core/renderer_opengl/texture_downloader_es.cpp b/src/video_core/renderer_opengl/texture_downloader_es.cpp
index 4e96cfaa9..fcf5e99bb 100644
--- a/src/video_core/renderer_opengl/texture_downloader_es.cpp
+++ b/src/video_core/renderer_opengl/texture_downloader_es.cpp
@@ -6,7 +6,7 @@
 #include <vector>
 #include <fmt/chrono.h>
 #include "common/logging/log.h"
-#include "video_core/rasterizer_cache/rasterizer_cache.h"
+#include "video_core/rasterizer_cache/rasterizer_cache_utils.h"
 #include "video_core/renderer_opengl/gl_state.h"
 #include "video_core/renderer_opengl/texture_downloader_es.h"
 #include "shaders/depth_to_color.frag"