From f8af1378b6ec78b7c4b2f667869203990f1cd29a Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Thu, 28 Sep 2023 13:01:27 -0700 Subject: [PATCH 1/3] Add initial support for 4x MSAA in OpenGLES backend. --- impeller/renderer/backend/gles/gles.h | 2 + .../renderer/backend/gles/proc_table_gles.h | 16 ++++---- .../renderer/backend/gles/render_pass_gles.cc | 3 -- .../renderer/backend/gles/texture_gles.cc | 39 ++++++++++++++++++- impeller/renderer/backend/gles/texture_gles.h | 1 + 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/impeller/renderer/backend/gles/gles.h b/impeller/renderer/backend/gles/gles.h index 599e3c9433c97..9bacfc87db4b3 100644 --- a/impeller/renderer/backend/gles/gles.h +++ b/impeller/renderer/backend/gles/gles.h @@ -4,6 +4,8 @@ #pragma once +// IWYU pragma: begin_exports #include "GLES3/gl3.h" #define GL_GLEXT_PROTOTYPES #include "GLES2/gl2ext.h" +// IWYU pragma: end_exports diff --git a/impeller/renderer/backend/gles/proc_table_gles.h b/impeller/renderer/backend/gles/proc_table_gles.h index 0af40009cdf13..eac2b77e59bb1 100644 --- a/impeller/renderer/backend/gles/proc_table_gles.h +++ b/impeller/renderer/backend/gles/proc_table_gles.h @@ -6,12 +6,10 @@ #include #include -#include #include "flutter/fml/logging.h" #include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" -#include "flutter/fml/trace_event.h" #include "impeller/renderer/backend/gles/capabilities_gles.h" #include "impeller/renderer/backend/gles/description_gles.h" #include "impeller/renderer/backend/gles/gles.h" @@ -170,11 +168,13 @@ struct GLProc { #define FOR_EACH_IMPELLER_GLES3_PROC(PROC) PROC(BlitFramebuffer); -#define FOR_EACH_IMPELLER_EXT_PROC(PROC) \ - PROC(DiscardFramebufferEXT); \ - PROC(PushDebugGroupKHR); \ - PROC(PopDebugGroupKHR); \ - PROC(ObjectLabelKHR); +#define FOR_EACH_IMPELLER_EXT_PROC(PROC) \ + PROC(DiscardFramebufferEXT); \ + PROC(FramebufferTexture2DMultisampleEXT) \ + PROC(PushDebugGroupKHR); \ + PROC(PopDebugGroupKHR); \ + PROC(ObjectLabelKHR); \ + PROC(RenderbufferStorageMultisampleEXT); enum class DebugResourceType { kTexture, @@ -188,7 +188,7 @@ enum class DebugResourceType { class ProcTableGLES { public: using Resolver = std::function; - ProcTableGLES(Resolver resolver); + explicit ProcTableGLES(Resolver resolver); ~ProcTableGLES(); diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc index 65ce6c2108189..735f8a85495f5 100644 --- a/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/impeller/renderer/backend/gles/render_pass_gles.cc @@ -4,10 +4,7 @@ #include "impeller/renderer/backend/gles/render_pass_gles.h" -#include - #include "flutter/fml/trace_event.h" -#include "impeller/base/config.h" #include "impeller/base/validation.h" #include "impeller/renderer/backend/gles/device_buffer_gles.h" #include "impeller/renderer/backend/gles/formats_gles.h" diff --git a/impeller/renderer/backend/gles/texture_gles.cc b/impeller/renderer/backend/gles/texture_gles.cc index 6c01e6b143e71..1ea904c602f0a 100644 --- a/impeller/renderer/backend/gles/texture_gles.cc +++ b/impeller/renderer/backend/gles/texture_gles.cc @@ -10,7 +10,6 @@ #include "flutter/fml/mapping.h" #include "flutter/fml/trace_event.h" #include "impeller/base/allocation.h" -#include "impeller/base/config.h" #include "impeller/base/validation.h" #include "impeller/core/formats.h" #include "impeller/renderer/backend/gles/formats_gles.h" @@ -33,6 +32,8 @@ HandleType ToHandleType(TextureGLES::Type type) { case TextureGLES::Type::kTexture: return HandleType::kTexture; case TextureGLES::Type::kRenderBuffer: + // MSAA textures are treated as render buffers. + case TextureGLES::Type::kRenderBufferMultisampled: return HandleType::kRenderBuffer; } FML_UNREACHABLE(); @@ -383,7 +384,7 @@ void TextureGLES::InitializeContentsIfNecessary() const { } } break; - case Type::kRenderBuffer: + case Type::kRenderBuffer: { auto render_buffer_format = ToRenderBufferFormat(GetTextureDescriptor().format); if (!render_buffer_format.has_value()) { @@ -399,7 +400,27 @@ void TextureGLES::InitializeContentsIfNecessary() const { size.height // height ); } + } break; + case Type::kRenderBufferMultisampled: { + auto render_buffer_msaa = + ToRenderBufferFormat(GetTextureDescriptor().format); + if (!render_buffer_msaa.has_value()) { + VALIDATION_LOG << "Invalid format for render-buffer MSAA image."; + return; + } + gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value()); + { + TRACE_EVENT0("impeller", "RenderBufferStorageInitialization"); + gl.RenderbufferStorageMultisampleEXT( + GL_RENDERBUFFER, // target + 4, // samples + render_buffer_msaa.value(), // internal format + size.width, // width + size.height // height + ); + } break; + } } } @@ -426,6 +447,8 @@ bool TextureGLES::Bind() const { gl.BindTexture(target.value(), handle.value()); } break; case Type::kRenderBuffer: + // MSAA textures are treated as render buffers. + case Type::kRenderBufferMultisampled: gl.BindRenderbuffer(GL_RENDERBUFFER, handle.value()); break; } @@ -510,6 +533,18 @@ bool TextureGLES::SetAsFramebufferAttachment(GLenum target, handle.value() // render-buffer ); break; + case Type::kRenderBufferMultisampled: + // Assume that when MSAA is enabled, we're using 4x MSAA. + FML_DCHECK(GetTextureDescriptor().sample_count == SampleCount::kCount4); + gl.FramebufferTexture2DMultisampleEXT( + target, // target + ToAttachmentPoint(point), // attachment + GL_TEXTURE_2D, // textarget + handle.value(), // texture + 0, // level + 4 // samples + ); + break; } return true; } diff --git a/impeller/renderer/backend/gles/texture_gles.h b/impeller/renderer/backend/gles/texture_gles.h index e2d2ae32c496e..effee19d80fbd 100644 --- a/impeller/renderer/backend/gles/texture_gles.h +++ b/impeller/renderer/backend/gles/texture_gles.h @@ -18,6 +18,7 @@ class TextureGLES final : public Texture, enum class Type { kTexture, kRenderBuffer, + kRenderBufferMultisampled, }; enum class IsWrapped { From 096d4ea5f6f33efaac2c4904814992478aadb1db Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 9 Oct 2023 13:13:59 -0700 Subject: [PATCH 2/3] Prepare for OpenGLES/MSAA. It errors out currently. --- impeller/renderer/backend/gles/capabilities_gles.cc | 13 ++++++++++++- impeller/renderer/backend/gles/capabilities_gles.h | 1 + impeller/renderer/backend/gles/render_pass_gles.cc | 6 +++--- impeller/renderer/backend/gles/texture_gles.cc | 7 +++++-- impeller/renderer/backend/gles/texture_gles.h | 1 - 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/impeller/renderer/backend/gles/capabilities_gles.cc b/impeller/renderer/backend/gles/capabilities_gles.cc index 45ad42e5ba447..6feaa730489a2 100644 --- a/impeller/renderer/backend/gles/capabilities_gles.cc +++ b/impeller/renderer/backend/gles/capabilities_gles.cc @@ -92,6 +92,17 @@ CapabilitiesGLES::CapabilitiesGLES(const ProcTableGLES& gl) { gl.GetDescription()->HasExtension("GL_OES_texture_border_clamp")) { supports_decal_sampler_address_mode_ = true; } + + if (gl.GetDescription()->HasExtension( + "GL_EXT_multisampled_render_to_texture")) { + supports_offscreen_msaa_ = true; + + // We hard-code 4x MSAA for now, so let's make sure it's supported. + GLint value = 0; + gl.GetIntegerv(GL_MAX_SAMPLES, &value); + FML_DCHECK(value == 4) << "Unexpected max samples: " << value << ". " + << "Only 4x MSAA is currently supported."; + } } size_t CapabilitiesGLES::GetMaxTextureUnits(ShaderStage stage) const { @@ -110,7 +121,7 @@ size_t CapabilitiesGLES::GetMaxTextureUnits(ShaderStage stage) const { } bool CapabilitiesGLES::SupportsOffscreenMSAA() const { - return false; + return supports_offscreen_msaa_; } bool CapabilitiesGLES::SupportsSSBO() const { diff --git a/impeller/renderer/backend/gles/capabilities_gles.h b/impeller/renderer/backend/gles/capabilities_gles.h index 20685f1565422..55220a5d5cb92 100644 --- a/impeller/renderer/backend/gles/capabilities_gles.h +++ b/impeller/renderer/backend/gles/capabilities_gles.h @@ -117,6 +117,7 @@ class CapabilitiesGLES final private: bool supports_decal_sampler_address_mode_ = false; + bool supports_offscreen_msaa_ = false; }; } // namespace impeller diff --git a/impeller/renderer/backend/gles/render_pass_gles.cc b/impeller/renderer/backend/gles/render_pass_gles.cc index aa25492524c33..6062fcff19fab 100644 --- a/impeller/renderer/backend/gles/render_pass_gles.cc +++ b/impeller/renderer/backend/gles/render_pass_gles.cc @@ -176,19 +176,19 @@ struct RenderPassData { if (auto color = TextureGLES::Cast(pass_data.color_attachment.get())) { if (!color->SetAsFramebufferAttachment( - GL_FRAMEBUFFER, fbo, TextureGLES::AttachmentPoint::kColor0)) { + GL_FRAMEBUFFER, TextureGLES::AttachmentPoint::kColor0)) { return false; } } if (auto depth = TextureGLES::Cast(pass_data.depth_attachment.get())) { if (!depth->SetAsFramebufferAttachment( - GL_FRAMEBUFFER, fbo, TextureGLES::AttachmentPoint::kDepth)) { + GL_FRAMEBUFFER, TextureGLES::AttachmentPoint::kDepth)) { return false; } } if (auto stencil = TextureGLES::Cast(pass_data.stencil_attachment.get())) { if (!stencil->SetAsFramebufferAttachment( - GL_FRAMEBUFFER, fbo, TextureGLES::AttachmentPoint::kStencil)) { + GL_FRAMEBUFFER, TextureGLES::AttachmentPoint::kStencil)) { return false; } } diff --git a/impeller/renderer/backend/gles/texture_gles.cc b/impeller/renderer/backend/gles/texture_gles.cc index 1ea904c602f0a..3c5f9afacac26 100644 --- a/impeller/renderer/backend/gles/texture_gles.cc +++ b/impeller/renderer/backend/gles/texture_gles.cc @@ -22,7 +22,11 @@ static TextureGLES::Type GetTextureTypeFromDescriptor( const auto render_target = static_cast(TextureUsage::kRenderTarget); if (usage == render_target) { - return TextureGLES::Type::kRenderBuffer; + if (desc.sample_count == SampleCount::kCount1) { + return TextureGLES::Type::kRenderBuffer; + } else { + return TextureGLES::Type::kRenderBufferMultisampled; + } } return TextureGLES::Type::kTexture; } @@ -506,7 +510,6 @@ static GLenum ToAttachmentPoint(TextureGLES::AttachmentPoint point) { } bool TextureGLES::SetAsFramebufferAttachment(GLenum target, - GLuint fbo, AttachmentPoint point) const { if (!IsValid()) { return false; diff --git a/impeller/renderer/backend/gles/texture_gles.h b/impeller/renderer/backend/gles/texture_gles.h index effee19d80fbd..7f5cb90e4d00b 100644 --- a/impeller/renderer/backend/gles/texture_gles.h +++ b/impeller/renderer/backend/gles/texture_gles.h @@ -46,7 +46,6 @@ class TextureGLES final : public Texture, kStencil, }; [[nodiscard]] bool SetAsFramebufferAttachment(GLenum target, - GLuint fbo, AttachmentPoint point) const; Type GetType() const; From 3a6e07704c60771e365a4e35dc273244f433c81b Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Mon, 16 Oct 2023 14:47:40 -0700 Subject: [PATCH 3/3] Format incompatibility but more progress. --- .../backend/gles/blit_command_gles.cc | 2 +- .../renderer/backend/gles/texture_gles.cc | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/impeller/renderer/backend/gles/blit_command_gles.cc b/impeller/renderer/backend/gles/blit_command_gles.cc index d6e56b6996081..5fbfc802e5f9c 100644 --- a/impeller/renderer/backend/gles/blit_command_gles.cc +++ b/impeller/renderer/backend/gles/blit_command_gles.cc @@ -41,7 +41,7 @@ static std::optional ConfigureFBO( gl.BindFramebuffer(fbo_type, fbo); if (!TextureGLES::Cast(*texture).SetAsFramebufferAttachment( - fbo_type, fbo, TextureGLES::AttachmentPoint::kColor0)) { + fbo_type, TextureGLES::AttachmentPoint::kColor0)) { VALIDATION_LOG << "Could not attach texture to framebuffer."; DeleteFBO(gl, fbo, fbo_type); return std::nullopt; diff --git a/impeller/renderer/backend/gles/texture_gles.cc b/impeller/renderer/backend/gles/texture_gles.cc index 3c5f9afacac26..2cfe0e8cd9540 100644 --- a/impeller/renderer/backend/gles/texture_gles.cc +++ b/impeller/renderer/backend/gles/texture_gles.cc @@ -386,7 +386,6 @@ void TextureGLES::InitializeContentsIfNecessary() const { nullptr // data ); } - } break; case Type::kRenderBuffer: { auto render_buffer_format = @@ -406,6 +405,27 @@ void TextureGLES::InitializeContentsIfNecessary() const { } } break; case Type::kRenderBufferMultisampled: { + gl.BindTexture(GL_TEXTURE_2D, handle.value()); + { + TRACE_EVENT0("impeller", "TexImage2DInitialization"); + TexImage2DData tex_data(GetTextureDescriptor().format); + // TODO: Remove this before submitting. + FML_LOG(ERROR) << "*** " << __PRETTY_FUNCTION__ + << " size_w=" << size.width << " h=" << size.height + << " iformat=" << tex_data.internal_format + << " eformat=" << tex_data.external_format; + // https://github.com/flutter/engine/blob/main/impeller/renderer/backend/gles/texture_gles.cc#L96 + gl.TexImage2D(GL_TEXTURE_2D, // target + 0u, // LOD level (base mip level size checked) + tex_data.internal_format, // internal format + size.width, // width + size.height, // height + 0u, // border + tex_data.external_format, // format + tex_data.type, // type + nullptr // data + ); + } auto render_buffer_msaa = ToRenderBufferFormat(GetTextureDescriptor().format); if (!render_buffer_msaa.has_value()) {