From 8cafe856f072737fa272da18e4e1618d3fec45e5 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin <stenzek@gmail.com> Date: Tue, 26 Jan 2021 01:34:13 +1000 Subject: [PATCH] OpenGLHostDisplay: Work around functions unavailable in GLES2 --- src/common/gl/texture.cpp | 23 ++++++++++----- src/frontend-common/opengl_host_display.cpp | 31 ++++++++++++++------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/common/gl/texture.cpp b/src/common/gl/texture.cpp index 065991cc3..c36e55ecc 100644 --- a/src/common/gl/texture.cpp +++ b/src/common/gl/texture.cpp @@ -184,24 +184,33 @@ void Texture::GetTextureSubImage(GLuint texture, GLint level, GLint xoffset, GLi return; } + GLenum target = GL_READ_FRAMEBUFFER; + GLenum target_binding = GL_READ_FRAMEBUFFER_BINDING; + if (GLAD_GL_ES_VERSION_2_0 && !GLAD_GL_ES_VERSION_3_0) + { + // GLES2 doesn't have GL_READ_FRAMEBUFFER. + target = GL_FRAMEBUFFER; + target_binding = GL_FRAMEBUFFER_BINDING; + } + Assert(depth == 1); GLuint old_read_fbo; - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, reinterpret_cast<GLint*>(&old_read_fbo)); + glGetIntegerv(target_binding, reinterpret_cast<GLint*>(&old_read_fbo)); GLuint temp_fbo; glGenFramebuffers(1, &temp_fbo); - glBindFramebuffer(GL_FRAMEBUFFER, temp_fbo); + glBindFramebuffer(target, temp_fbo); if (zoffset > 0 && (GLAD_GL_VERSION_3_0 || GLAD_GL_ES_VERSION_3_0)) - glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, level, zoffset); + glFramebufferTextureLayer(target, GL_COLOR_ATTACHMENT0, texture, level, zoffset); else - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level); + glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, level); - DebugAssert(glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); + DebugAssert(glCheckFramebufferStatus(target) == GL_FRAMEBUFFER_COMPLETE); glReadPixels(xoffset, yoffset, width, height, format, type, pixels); - glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fbo); + glBindFramebuffer(target, old_read_fbo); glDeleteFramebuffers(1, &temp_fbo); } -} // namespace GL \ No newline at end of file +} // namespace GL diff --git a/src/frontend-common/opengl_host_display.cpp b/src/frontend-common/opengl_host_display.cpp index 9e07b82da..2fdc5e333 100644 --- a/src/frontend-common/opengl_host_display.cpp +++ b/src/frontend-common/opengl_host_display.cpp @@ -104,17 +104,23 @@ void OpenGLHostDisplay::UpdateTexture(HostDisplayTexture* texture, u32 x, u32 y, GLint old_texture_binding = 0, old_alignment = 0, old_row_length = 0; glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_texture_binding); - glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_alignment); - glGetIntegerv(GL_UNPACK_ROW_LENGTH, &old_row_length); - glBindTexture(GL_TEXTURE_2D, tex->GetGLID()); + + glGetIntegerv(GL_UNPACK_ALIGNMENT, &old_alignment); glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); - glPixelStorei(GL_UNPACK_ROW_LENGTH, texture_data_stride / GetDisplayPixelFormatSize(texture->GetFormat())); + + if (!m_use_gles2_draw_path) + { + glGetIntegerv(GL_UNPACK_ROW_LENGTH, &old_row_length); + glPixelStorei(GL_UNPACK_ROW_LENGTH, texture_data_stride / GetDisplayPixelFormatSize(texture->GetFormat())); + } glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, gl_format, gl_type, texture_data); + if (!m_use_gles2_draw_path) + glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length); + glPixelStorei(GL_UNPACK_ALIGNMENT, old_alignment); - glPixelStorei(GL_UNPACK_ROW_LENGTH, old_row_length); glBindTexture(GL_TEXTURE_2D, old_texture_binding); } @@ -131,9 +137,12 @@ bool OpenGLHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayP GLint old_alignment = 0, old_row_length = 0; glGetIntegerv(GL_PACK_ALIGNMENT, &old_alignment); - glGetIntegerv(GL_PACK_ROW_LENGTH, &old_row_length); glPixelStorei(GL_PACK_ALIGNMENT, alignment); - glPixelStorei(GL_PACK_ROW_LENGTH, out_data_stride / GetDisplayPixelFormatSize(texture_format)); + if (!m_use_gles2_draw_path) + { + glGetIntegerv(GL_PACK_ROW_LENGTH, &old_row_length); + glPixelStorei(GL_PACK_ROW_LENGTH, out_data_stride / GetDisplayPixelFormatSize(texture_format)); + } const GLuint texture = static_cast<GLuint>(reinterpret_cast<uintptr_t>(texture_handle)); const auto [gl_internal_format, gl_format, gl_type] = @@ -143,7 +152,8 @@ bool OpenGLHostDisplay::DownloadTexture(const void* texture_handle, HostDisplayP out_data); glPixelStorei(GL_PACK_ALIGNMENT, old_alignment); - glPixelStorei(GL_PACK_ROW_LENGTH, old_row_length); + if (!m_use_gles2_draw_path) + glPixelStorei(GL_PACK_ROW_LENGTH, old_row_length); return true; } @@ -333,7 +343,9 @@ bool OpenGLHostDisplay::CreateRenderDevice(const WindowInfo& wi, std::string_vie bool OpenGLHostDisplay::InitializeRenderDevice(std::string_view shader_cache_directory, bool debug_device, bool threaded_presentation) { - glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, reinterpret_cast<GLint*>(&m_uniform_buffer_alignment)); + m_use_gles2_draw_path = (GetRenderAPI() == HostDisplay::RenderAPI::OpenGLES && !GLAD_GL_ES_VERSION_3_0); + if (!m_use_gles2_draw_path) + glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, reinterpret_cast<GLint*>(&m_uniform_buffer_alignment)); if (debug_device && GLAD_GL_KHR_debug) { @@ -483,7 +495,6 @@ void OpenGLHostDisplay::DestroyImGuiContext() bool OpenGLHostDisplay::CreateResources() { - m_use_gles2_draw_path = (GetRenderAPI() == HostDisplay::RenderAPI::OpenGLES && !GLAD_GL_ES_VERSION_3_0); if (!m_use_gles2_draw_path) { static constexpr char fullscreen_quad_vertex_shader[] = R"(