From bcc20421540cc0eab6d006106460d5e8b7c27fe5 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 6 Dec 2023 23:35:40 +1000 Subject: [PATCH] OpenGLDevice: GLES fixes --- src/util/opengl_device.cpp | 6 ++++-- src/util/opengl_device.h | 6 +++--- src/util/opengl_texture.cpp | 38 +++++++++++++++++++++++++++++++------ src/util/opengl_texture.h | 2 +- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/util/opengl_device.cpp b/src/util/opengl_device.cpp index f9d534d99..1de8f9a1f 100644 --- a/src/util/opengl_device.cpp +++ b/src/util/opengl_device.cpp @@ -75,7 +75,8 @@ bool OpenGLDevice::DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, glPixelStorei(GL_PACK_ALIGNMENT, alignment); glPixelStorei(GL_PACK_ROW_LENGTH, out_data_stride / T->GetPixelSize()); - const auto [gl_internal_format, gl_format, gl_type] = OpenGLTexture::GetPixelFormatMapping(T->GetFormat()); + const auto [gl_internal_format, gl_format, gl_type] = + OpenGLTexture::GetPixelFormatMapping(T->GetFormat(), m_gl_context->IsGLES()); const u32 layer = 0; const u32 level = 0; @@ -105,7 +106,8 @@ bool OpenGLDevice::DownloadTexture(GPUTexture* texture, u32 x, u32 y, u32 width, bool OpenGLDevice::SupportsTextureFormat(GPUTexture::Format format) const { - const auto [gl_internal_format, gl_format, gl_type] = OpenGLTexture::GetPixelFormatMapping(format); + const auto [gl_internal_format, gl_format, gl_type] = + OpenGLTexture::GetPixelFormatMapping(format, m_gl_context->IsGLES()); return (gl_internal_format != static_cast(0)); } diff --git a/src/util/opengl_device.h b/src/util/opengl_device.h index c584837f6..fd0a36ceb 100644 --- a/src/util/opengl_device.h +++ b/src/util/opengl_device.h @@ -32,10 +32,9 @@ public: { return GetInstance().m_texture_stream_buffer.get(); } + ALWAYS_INLINE static bool IsGLES() { return GetInstance().m_gl_context->IsGLES(); } static void BindUpdateTextureUnit(); - ALWAYS_INLINE GL::Context* GetGLContext() const { return m_gl_context.get(); } - RenderAPI GetRenderAPI() const override; bool HasSurface() const override; @@ -122,7 +121,8 @@ public: void UnbindPipeline(const OpenGLPipeline* pl); protected: - bool CreateDevice(const std::string_view& adapter, bool threaded_presentation, FeatureMask disabled_features) override; + bool CreateDevice(const std::string_view& adapter, bool threaded_presentation, + FeatureMask disabled_features) override; void DestroyDevice() override; bool ReadPipelineCache(const std::string& filename) override; diff --git a/src/util/opengl_texture.cpp b/src/util/opengl_texture.cpp index ee3ece6e7..452c10f99 100644 --- a/src/util/opengl_texture.cpp +++ b/src/util/opengl_texture.cpp @@ -24,7 +24,7 @@ static constexpr u32 TEXTURE_UPLOAD_ALIGNMENT = 64; // We need 32 here for AVX2, so 64 is also fine. static constexpr u32 TEXTURE_UPLOAD_PITCH_ALIGNMENT = 64; -const std::tuple& OpenGLTexture::GetPixelFormatMapping(GPUTexture::Format format) +const std::tuple& OpenGLTexture::GetPixelFormatMapping(GPUTexture::Format format, bool gles) { static constexpr std::array, static_cast(GPUTexture::Format::MaxCount)> mapping = {{ @@ -50,7 +50,32 @@ const std::tuple& OpenGLTexture::GetPixelFormatMapping(G {GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // RGB10A2 }}; - return mapping[static_cast(format)]; + // GLES doesn't have the non-normalized 16-bit formats.. use float and hope for the best, lol. + static constexpr std::array, static_cast(GPUTexture::Format::MaxCount)> + mapping_gles = {{ + {}, // Unknown + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}, // RGBA8 + {GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE}, // BGRA8 + {GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565 + {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // RGBA5551 + {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8 + {GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_SHORT}, // D16 + {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16 + {GL_R16F, GL_RED, GL_HALF_FLOAT}, // R16F + {GL_R32I, GL_RED, GL_INT}, // R32I + {GL_R32UI, GL_RED, GL_UNSIGNED_INT}, // R32U + {GL_R32F, GL_RED, GL_FLOAT}, // R32F + {GL_RG8, GL_RG, GL_UNSIGNED_BYTE}, // RG8 + {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16 + {GL_RG16F, GL_RG, GL_HALF_FLOAT}, // RG16F + {GL_RG32F, GL_RG, GL_FLOAT}, // RG32F + {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16 + {GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT}, // RGBA16F + {GL_RGBA32F, GL_RGBA, GL_FLOAT}, // RGBA32F + {GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // RGB10A2 + }}; + + return gles ? mapping_gles[static_cast(format)] : mapping[static_cast(format)]; } OpenGLTexture::OpenGLTexture() = default; @@ -84,7 +109,7 @@ bool OpenGLTexture::Create(u32 width, u32 height, u32 layers, u32 levels, u32 sa const GLenum target = ((samples > 1) ? GL_TEXTURE_2D_MULTISAMPLE : ((layers > 1) ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D)); - const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(format); + const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(format, OpenGLDevice::IsGLES()); OpenGLDevice::BindUpdateTextureUnit(); @@ -200,7 +225,7 @@ bool OpenGLTexture::Update(u32 x, u32 y, u32 width, u32 height, const void* data // Worth using the PBO? Driver probably knows better... const GLenum target = GetGLTarget(); - const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_format); + const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_format, OpenGLDevice::IsGLES()); const u32 preferred_pitch = Common::AlignUpPow2(static_cast(width) * GetPixelSize(), TEXTURE_UPLOAD_PITCH_ALIGNMENT); const u32 map_size = preferred_pitch * static_cast(height); @@ -280,7 +305,7 @@ void OpenGLTexture::Unmap() glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / GetPixelSize()); - const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_format); + const auto [gl_internal_format, gl_format, gl_type] = GetPixelFormatMapping(m_format, OpenGLDevice::IsGLES()); if (IsTextureArray()) { glTexSubImage3D(target, m_map_level, m_map_x, m_map_y, m_map_layer, m_map_width, m_map_height, 1, gl_format, @@ -469,7 +494,8 @@ void OpenGLDevice::CommitClear(OpenGLTexture* tex) if (glClearTexImage) { - const auto [gl_internal_format, gl_format, gl_type] = OpenGLTexture::GetPixelFormatMapping(tex->GetFormat()); + const auto [gl_internal_format, gl_format, gl_type] = + OpenGLTexture::GetPixelFormatMapping(tex->GetFormat(), m_gl_context->IsGLES()); glClearTexImage(tex->GetGLId(), 0, gl_format, gl_type, &tex->GetClearValue()); } else diff --git a/src/util/opengl_texture.h b/src/util/opengl_texture.h index 3cea4f292..9c5e9fb3e 100644 --- a/src/util/opengl_texture.h +++ b/src/util/opengl_texture.h @@ -20,7 +20,7 @@ public: ~OpenGLTexture(); static bool UseTextureStorage(bool multisampled); - static const std::tuple& GetPixelFormatMapping(Format format); + static const std::tuple& GetPixelFormatMapping(Format format, bool gles); ALWAYS_INLINE GLuint GetGLId() const { return m_id; } bool IsValid() const override { return m_id != 0; }