From 1579f96397892153b3a76c5701a0a4e543619a97 Mon Sep 17 00:00:00 2001 From: emufan4568 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(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(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(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& watcher, PAddr address, GLenum gl_face) - : watcher(watcher), address(address), gl_face(gl_face) {} + Face(std::shared_ptr& watcher, PAddr address) + : watcher(watcher), address(address) {} std::shared_ptr& watcher; PAddr address; - GLenum gl_face; }; const std::array 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(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 #include #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"