From 12d400b76ae92847b3e8961a330b478d30a176aa Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 3 Oct 2022 14:04:56 +1000 Subject: [PATCH] OpenGLHostDisplay: Replace GL ID handle with texture class --- src/common/gl/texture.cpp | 17 +++- src/common/gl/texture.h | 8 +- src/core/gpu_hw_opengl.cpp | 26 +++--- src/frontend-common/imgui_impl_opengl3.cpp | 29 +++---- src/frontend-common/opengl_host_display.cpp | 93 ++++++--------------- 5 files changed, 63 insertions(+), 110 deletions(-) diff --git a/src/common/gl/texture.cpp b/src/common/gl/texture.cpp index 461fee141..2d821e66a 100644 --- a/src/common/gl/texture.cpp +++ b/src/common/gl/texture.cpp @@ -96,6 +96,15 @@ bool Texture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 samples, glTexStorage3D(target, levels, internal_format, width, height, layers); else glTexStorage2D(target, levels, internal_format, width, height); + + if (data) + { + // TODO: Fix data for mipmaps here. + if (layers > 1) + glTexSubImage3D(target, 0, 0, 0, 0, width, height, layers, format, type, data); + else + glTexSubImage2D(target, 0, 0, 0, width, height, format, type, data); + } } else { @@ -200,7 +209,7 @@ void Texture::ReplaceSubImage(u32 layer, u32 level, u32 x, u32 y, u32 width, u32 glTexSubImage2D(target, level, x, y, width, height, format, type, data); } -void Texture::SetLinearFilter(bool enabled) +void Texture::SetLinearFilter(bool enabled) const { Assert(!IsMultisampled()); @@ -255,18 +264,18 @@ void Texture::Destroy() m_samples = 0; } -void Texture::Bind() +void Texture::Bind() const { glBindTexture(GetGLTarget(), m_id); } -void Texture::BindFramebuffer(GLenum target /*= GL_DRAW_FRAMEBUFFER*/) +void Texture::BindFramebuffer(GLenum target /*= GL_DRAW_FRAMEBUFFER*/) const { DebugAssert(m_fbo_id != 0); glBindFramebuffer(target, m_fbo_id); } -void Texture::Unbind() +void Texture::Unbind() const { glBindTexture(GetGLTarget(), 0); } diff --git a/src/common/gl/texture.h b/src/common/gl/texture.h index b9d2d1a1f..f5fc25b06 100644 --- a/src/common/gl/texture.h +++ b/src/common/gl/texture.h @@ -23,7 +23,7 @@ public: void Destroy(); bool UseTextureStorage() const; - void SetLinearFilter(bool enabled); + void SetLinearFilter(bool enabled) const; ALWAYS_INLINE bool IsValid() const { return m_id != 0; } ALWAYS_INLINE bool IsTextureArray() const { return m_layers > 1; } @@ -42,9 +42,9 @@ public: (IsTextureArray() ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D)); } - void Bind(); - void BindFramebuffer(GLenum target = GL_DRAW_FRAMEBUFFER); - void Unbind(); + void Bind() const; + void BindFramebuffer(GLenum target = GL_DRAW_FRAMEBUFFER) const; + void Unbind() const; Texture& operator=(const Texture& copy) = delete; Texture& operator=(Texture&& moved); diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index f85b5875b..0f2a6f5c3 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -867,16 +867,14 @@ void GPU_HW_OpenGL::UpdateDisplay() { UpdateVRAMReadTexture(); - g_host_display->SetDisplayTexture(reinterpret_cast(static_cast(m_vram_read_texture.GetGLId())), - HostDisplayPixelFormat::RGBA8, m_vram_read_texture.GetWidth(), - static_cast(m_vram_read_texture.GetHeight()), 0, - m_vram_read_texture.GetHeight(), m_vram_read_texture.GetWidth(), - -static_cast(m_vram_read_texture.GetHeight())); + g_host_display->SetDisplayTexture( + &m_vram_read_texture, HostDisplayPixelFormat::RGBA8, m_vram_read_texture.GetWidth(), + static_cast(m_vram_read_texture.GetHeight()), 0, m_vram_read_texture.GetHeight(), + m_vram_read_texture.GetWidth(), -static_cast(m_vram_read_texture.GetHeight())); } else { - g_host_display->SetDisplayTexture(reinterpret_cast(static_cast(m_vram_texture.GetGLId())), - HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(), + g_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(), static_cast(m_vram_texture.GetHeight()), 0, m_vram_texture.GetHeight(), m_vram_texture.GetWidth(), -static_cast(m_vram_texture.GetHeight())); } @@ -916,8 +914,7 @@ void GPU_HW_OpenGL::UpdateDisplay() } else { - g_host_display->SetDisplayTexture(reinterpret_cast(static_cast(m_vram_texture.GetGLId())), - HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(), + g_host_display->SetDisplayTexture(&m_vram_texture, HostDisplayPixelFormat::RGBA8, m_vram_texture.GetWidth(), m_vram_texture.GetHeight(), scaled_vram_offset_x, m_vram_texture.GetHeight() - scaled_vram_offset_y, scaled_display_width, -static_cast(scaled_display_height)); @@ -963,9 +960,9 @@ void GPU_HW_OpenGL::UpdateDisplay() } else { - g_host_display->SetDisplayTexture(reinterpret_cast(static_cast(m_display_texture.GetGLId())), - HostDisplayPixelFormat::RGBA8, m_display_texture.GetWidth(), - m_display_texture.GetHeight(), 0, scaled_display_height, scaled_display_width, + g_host_display->SetDisplayTexture(&m_display_texture, HostDisplayPixelFormat::RGBA8, + m_display_texture.GetWidth(), m_display_texture.GetHeight(), 0, + scaled_display_height, scaled_display_width, -static_cast(scaled_display_height)); } @@ -1356,9 +1353,8 @@ void GPU_HW_OpenGL::DownsampleFramebufferBoxFilter(GL::Texture& source, u32 left RestoreGraphicsAPIState(); - g_host_display->SetDisplayTexture(reinterpret_cast(static_cast(m_downsample_texture.GetGLId())), - HostDisplayPixelFormat::RGBA8, m_downsample_texture.GetWidth(), - m_downsample_texture.GetHeight(), ds_left, + g_host_display->SetDisplayTexture(&m_downsample_texture, HostDisplayPixelFormat::RGBA8, + m_downsample_texture.GetWidth(), m_downsample_texture.GetHeight(), ds_left, m_downsample_texture.GetHeight() - ds_top, ds_width, -static_cast(ds_height)); } diff --git a/src/frontend-common/imgui_impl_opengl3.cpp b/src/frontend-common/imgui_impl_opengl3.cpp index 4210fe28e..952be29ad 100644 --- a/src/frontend-common/imgui_impl_opengl3.cpp +++ b/src/frontend-common/imgui_impl_opengl3.cpp @@ -105,13 +105,14 @@ // GL includes #include "common/gl/loader.h" +#include "common/gl/texture.h" // OpenGL Data struct ImGui_ImplOpenGL3_Data { GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings. - GLuint FontTexture; + GL::Texture FontTexture; GLuint ShaderHandle; GLint AttribLocationTex; // Uniforms location GLint AttribLocationProjMtx; @@ -292,7 +293,9 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) glScissor((int)clip_min.x, (int)((float)fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)); // Bind texture, Draw - glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); + const GL::Texture* tex = static_cast(pcmd->GetTexID()); + if (tex) + tex->Bind(); glDrawElementsBaseVertex(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)), (GLint)pcmd->VtxOffset); } } @@ -313,19 +316,11 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture() // Upload texture to graphics system // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling) - if (bd->FontTexture == 0) - glGenTextures(1, &bd->FontTexture); - - glBindTexture(GL_TEXTURE_2D, bd->FontTexture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + bd->FontTexture.Create(width, height, 1, 1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + bd->FontTexture.SetLinearFilter(true); // Store our identifier - io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture); + io.Fonts->SetTexID(&bd->FontTexture); return true; } @@ -333,12 +328,8 @@ void ImGui_ImplOpenGL3_DestroyFontsTexture() { ImGuiIO& io = ImGui::GetIO(); ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); - if (bd->FontTexture) - { - glDeleteTextures(1, &bd->FontTexture); - io.Fonts->SetTexID(0); - bd->FontTexture = 0; - } + if (bd->FontTexture.IsValid()) + bd->FontTexture.Destroy(); } // If you get an error please report on github. You may try different GL context version or GLSL version. See GL<>GLSL version table at the top of this file. diff --git a/src/frontend-common/opengl_host_display.cpp b/src/frontend-common/opengl_host_display.cpp index 96ce53af5..30f29b0ce 100644 --- a/src/frontend-common/opengl_host_display.cpp +++ b/src/frontend-common/opengl_host_display.cpp @@ -19,18 +19,22 @@ enum : u32 class OpenGLHostDisplayTexture final : public HostDisplayTexture { public: - OpenGLHostDisplayTexture(GL::Texture texture, HostDisplayPixelFormat format); - ~OpenGLHostDisplayTexture() override; + OpenGLHostDisplayTexture(GL::Texture texture, HostDisplayPixelFormat format) + : m_texture(std::move(texture)), m_format(format) + { + } - void* GetHandle() const override; - u32 GetWidth() const override; - u32 GetHeight() const override; - u32 GetLayers() const override; - u32 GetLevels() const override; - u32 GetSamples() const override; - HostDisplayPixelFormat GetFormat() const override; + ~OpenGLHostDisplayTexture() = default; - GLuint GetGLID() const; + void* GetHandle() const override { return const_cast(&m_texture); } + + u32 GetWidth() const override { return m_texture.GetWidth(); } + u32 GetHeight() const override { return m_texture.GetHeight(); } + u32 GetLayers() const override { return m_texture.GetLayers(); } + u32 GetLevels() const override { return m_texture.GetLevels(); } + u32 GetSamples() const override { return m_texture.GetSamples(); } + HostDisplayPixelFormat GetFormat() const override { return m_format; } + GLuint GetGLID() const { return m_texture.GetGLId(); } bool BeginUpdate(u32 width, u32 height, void** out_buffer, u32* out_pitch) override; void EndUpdate(u32 x, u32 y, u32 width, u32 height) override; @@ -136,11 +140,11 @@ bool OpenGLHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayP glPixelStorei(GL_PACK_ROW_LENGTH, out_data_stride / GetDisplayPixelFormatSize(texture_format)); } - const GLuint texture = static_cast(reinterpret_cast(texture_handle)); + const GL::Texture* texture = static_cast(texture_handle); const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_gl_context->IsGLES(), texture_format); - GL::Texture::GetTextureSubImage(texture, 0, x, y, 0, width, height, 1, gl_format, gl_type, height * out_data_stride, - out_data); + GL::Texture::GetTextureSubImage(texture->GetGLId(), 0, x, y, 0, width, height, 1, gl_format, gl_type, + height * out_data_stride, out_data); glPixelStorei(GL_PACK_ALIGNMENT, old_alignment); if (!m_use_gles2_draw_path) @@ -689,13 +693,15 @@ void OpenGLHostDisplay::RenderDisplay(s32 left, s32 bottom, s32 width, s32 heigh u32 texture_width, s32 texture_height, s32 texture_view_x, s32 texture_view_y, s32 texture_view_width, s32 texture_view_height, bool linear_filter) { + const GL::Texture* texture = static_cast(texture_handle); + glViewport(left, bottom, width, height); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); - glBindTexture(GL_TEXTURE_2D, static_cast(reinterpret_cast(texture_handle))); m_display_program.Bind(); + texture->Bind(); const bool linear = IsUsingLinearFiltering(); @@ -716,9 +722,7 @@ void OpenGLHostDisplay::RenderDisplay(s32 left, s32 bottom, s32 width, s32 heigh } else { - // TODO: This sucks. - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear ? GL_LINEAR : GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); + texture->SetLinearFilter(linear_filter); DrawFullscreenQuadES2(m_display_texture_view_x, m_display_texture_view_y, m_display_texture_view_width, m_display_texture_view_height, m_display_texture_width, m_display_texture_height); @@ -884,7 +888,7 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_ texture_width, texture_height, texture_view_x, texture_view_y, texture_view_width, texture_view_height, IsUsingLinearFiltering()); - texture_handle = reinterpret_cast(static_cast(m_post_processing_input_texture.GetGLId())); + texture_handle = &m_post_processing_input_texture; texture_width = m_post_processing_input_texture.GetWidth(); texture_height = m_post_processing_input_texture.GetHeight(); texture_view_x = final_left; @@ -909,8 +913,8 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_ } pps.program.Bind(); - glBindSampler(0, m_display_linear_sampler); - glBindTexture(GL_TEXTURE_2D, static_cast(reinterpret_cast(texture_handle))); + + static_cast(texture_handle)->Bind(); glBindSampler(0, m_display_nearest_sampler); const auto map_result = m_post_processing_ubo->Map(m_uniform_buffer_alignment, pps.uniforms_size); @@ -924,7 +928,7 @@ void OpenGLHostDisplay::ApplyPostProcessingChain(GLuint final_target, s32 final_ glDrawArrays(GL_TRIANGLES, 0, 3); if (i != final_stage) - texture_handle = reinterpret_cast(static_cast(pps.output_texture.GetGLId())); + texture_handle = &pps.output_texture; } glBindSampler(0, 0); @@ -1059,53 +1063,6 @@ GL::StreamBuffer* OpenGLHostDisplay::GetTextureStreamBuffer() return m_texture_stream_buffer.get(); } -OpenGLHostDisplayTexture::OpenGLHostDisplayTexture(GL::Texture texture, HostDisplayPixelFormat format) - : m_texture(std::move(texture)), m_format(format) -{ -} - -OpenGLHostDisplayTexture::~OpenGLHostDisplayTexture() = default; - -void* OpenGLHostDisplayTexture::GetHandle() const -{ - return reinterpret_cast(static_cast(m_texture.GetGLId())); -} - -u32 OpenGLHostDisplayTexture::GetWidth() const -{ - return m_texture.GetWidth(); -} - -u32 OpenGLHostDisplayTexture::GetHeight() const -{ - return m_texture.GetHeight(); -} - -u32 OpenGLHostDisplayTexture::GetLayers() const -{ - return 1; -} - -u32 OpenGLHostDisplayTexture::GetLevels() const -{ - return 1; -} - -u32 OpenGLHostDisplayTexture::GetSamples() const -{ - return m_texture.GetSamples(); -} - -HostDisplayPixelFormat OpenGLHostDisplayTexture::GetFormat() const -{ - return m_format; -} - -GLuint OpenGLHostDisplayTexture::GetGLID() const -{ - return m_texture.GetGLId(); -} - bool OpenGLHostDisplayTexture::BeginUpdate(u32 width, u32 height, void** out_buffer, u32* out_pitch) { const u32 pixel_size = HostDisplay::GetDisplayPixelFormatSize(m_format);