From 90e1284d83b34bc5aaf73c9f384c63048259f383 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Thu, 30 Dec 2021 19:54:27 +1000 Subject: [PATCH] GS: Move mipmap generation flag to GSTexture --- pcsx2/GS/Renderers/Common/GSTexture.cpp | 11 +++++++++++ pcsx2/GS/Renderers/Common/GSTexture.h | 10 ++++++++-- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 2 ++ pcsx2/GS/Renderers/HW/GSRendererNew.cpp | 2 +- pcsx2/GS/Renderers/OpenGL/GSTextureOGL.cpp | 23 ++++++++++------------ pcsx2/GS/Renderers/OpenGL/GSTextureOGL.h | 2 -- 6 files changed, 32 insertions(+), 18 deletions(-) diff --git a/pcsx2/GS/Renderers/Common/GSTexture.cpp b/pcsx2/GS/Renderers/Common/GSTexture.cpp index e0d62e1be2..8d4f6f192c 100644 --- a/pcsx2/GS/Renderers/Common/GSTexture.cpp +++ b/pcsx2/GS/Renderers/Common/GSTexture.cpp @@ -22,9 +22,11 @@ GSTexture::GSTexture() , m_size(0, 0) , m_committed_size(0, 0) , m_gpu_page_size(0, 0) + , m_mipmap_levels(0) , m_type(Type::Invalid) , m_format(Format::Invalid) , m_sparse(false) + , m_needs_mipmaps_generated(true) , last_frame_used(0) , LikelyOffset(false) , OffsetHack_modx(0.0f) @@ -32,6 +34,15 @@ GSTexture::GSTexture() { } +void GSTexture::GenerateMipmapsIfNeeded() +{ + if (!m_needs_mipmaps_generated || m_mipmap_levels <= 1) + return; + + m_needs_mipmaps_generated = false; + GenerateMipmap(); +} + void GSTexture::CommitRegion(const GSVector2i& region) { if (!m_sparse) diff --git a/pcsx2/GS/Renderers/Common/GSTexture.h b/pcsx2/GS/Renderers/Common/GSTexture.h index bcfc2625c7..a751f62cc3 100644 --- a/pcsx2/GS/Renderers/Common/GSTexture.h +++ b/pcsx2/GS/Renderers/Common/GSTexture.h @@ -26,7 +26,7 @@ public: int pitch; }; - enum class Type + enum class Type : u8 { Invalid = 0, RenderTarget = 1, @@ -37,7 +37,7 @@ public: SparseDepthStencil, }; - enum class Format + enum class Format : u8 { Invalid = 0, ///< Used for initialization Color, ///< Standard (RGBA8) color texture @@ -54,9 +54,11 @@ protected: GSVector2i m_size; GSVector2i m_committed_size; GSVector2i m_gpu_page_size; + int m_mipmap_levels; Type m_type; Format m_format; bool m_sparse; + bool m_needs_mipmaps_generated; public: GSTexture(); @@ -84,10 +86,14 @@ public: int GetWidth() const { return m_size.x; } int GetHeight() const { return m_size.y; } GSVector2i GetSize() const { return m_size; } + int GetMipmapLevels() const { return m_mipmap_levels; } Type GetType() const { return m_type; } Format GetFormat() const { return m_format; } + void GenerateMipmapsIfNeeded(); + void ClearMipmapGenerationFlag() { m_needs_mipmaps_generated = false; } + virtual void CommitPages(const GSVector2i& region, bool commit) {} void CommitRegion(const GSVector2i& region); void Commit(); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index ae96a034c8..028d8c6361 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -1420,6 +1420,8 @@ void GSRendererHW::Draw() m_src->UpdateLayer(MIP_TEX0, r, layer - m_lod.x); } + // we don't need to generate mipmaps since they were provided + m_src->m_texture->ClearMipmapGenerationFlag(); m_vt.m_min.t = tmin; m_vt.m_max.t = tmax; } diff --git a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp index 0c49bb1106..a5fbdf0688 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererNew.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererNew.cpp @@ -948,7 +948,7 @@ void GSRendererNew::EmulateTextureSampler(const GSTextureCache::Source* tex) } else if (trilinear_auto) { - tex->m_texture->GenerateMipmap(); + tex->m_texture->GenerateMipmapsIfNeeded(); } // TC Offset Hack diff --git a/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.cpp index d53c2556e2..877e4915ba 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.cpp @@ -172,7 +172,7 @@ namespace PboPool } // namespace PboPool GSTextureOGL::GSTextureOGL(Type type, int w, int h, Format format, GLuint fbo_read, bool mipmap) - : m_clean(false), m_generate_mipmap(true), m_r_x(0), m_r_y(0), m_r_w(0), m_r_h(0), m_layer(0) + : m_clean(false), m_r_x(0), m_r_y(0), m_r_w(0), m_r_h(0), m_layer(0) { // OpenGL didn't like dimensions of size 0 m_size.x = std::max(1, w); @@ -182,7 +182,7 @@ GSTextureOGL::GSTextureOGL(Type type, int w, int h, Format format, GLuint fbo_re m_fbo_read = fbo_read; m_texture_id = 0; m_sparse = false; - m_max_layer = 1; + m_mipmap_levels = 1; int gl_fmt = 0; // Bunch of constant parameter @@ -251,7 +251,7 @@ GSTextureOGL::GSTextureOGL(Type type, int w, int h, Format format, GLuint fbo_re { case Type::Texture: // Only 32 bits input texture will be supported for mipmap - m_max_layer = mipmap && m_format == Format::Color ? (int)log2(std::max(w, h)) : 1; + m_mipmap_levels = mipmap && m_format == Format::Color ? (int)log2(std::max(w, h)) : 1; break; case Type::SparseRenderTarget: case Type::SparseDepthStencil: @@ -327,7 +327,7 @@ GSTextureOGL::GSTextureOGL(Type type, int w, int h, Format format, GLuint fbo_re throw std::bad_alloc(); } - glTextureStorage2D(m_texture_id, m_max_layer + GL_TEX_LEVEL_0, gl_fmt, m_size.x, m_size.y); + glTextureStorage2D(m_texture_id, m_mipmap_levels, gl_fmt, m_size.x, m_size.y); } GSTextureOGL::~GSTextureOGL() @@ -368,7 +368,7 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch, int { ASSERT(m_type != Type::DepthStencil && m_type != Type::Offscreen); - if (layer >= m_max_layer) + if (layer >= m_mipmap_levels) return true; // Default upload path for the texture is the Map/Unmap @@ -431,14 +431,14 @@ bool GSTextureOGL::Update(const GSVector4i& r, const void* data, int pitch, int PboPool::EndTransfer(); #endif - m_generate_mipmap = true; + m_needs_mipmaps_generated = true; return true; } bool GSTextureOGL::Map(GSMap& m, const GSVector4i* _r, int layer) { - if (layer >= m_max_layer) + if (layer >= m_mipmap_levels) return false; GSVector4i r = _r ? *_r : GSVector4i(0, 0, m_size.x, m_size.y); @@ -491,7 +491,7 @@ void GSTextureOGL::Unmap() PboPool::EndTransfer(); - m_generate_mipmap = true; + m_needs_mipmaps_generated = true; GL_POP(); // PUSH is in Map } @@ -499,11 +499,8 @@ void GSTextureOGL::Unmap() void GSTextureOGL::GenerateMipmap() { - if (m_generate_mipmap && m_max_layer > 1) - { - glGenerateTextureMipmap(m_texture_id); - m_generate_mipmap = false; - } + ASSERT(m_mipmap_levels > 1); + glGenerateTextureMipmap(m_texture_id); } void GSTextureOGL::CommitPages(const GSVector2i& region, bool commit) diff --git a/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.h b/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.h index 54978673fa..3419b004f6 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.h +++ b/pcsx2/GS/Renderers/OpenGL/GSTextureOGL.h @@ -40,7 +40,6 @@ private: GLuint m_texture_id; // the texture id GLuint m_fbo_read; bool m_clean; - bool m_generate_mipmap; // Avoid alignment constrain //GSVector4i m_r; @@ -49,7 +48,6 @@ private: int m_r_w; int m_r_h; int m_layer; - int m_max_layer; // internal opengl format/type/alignment GLenum m_int_format;