diff --git a/engine/src/flutter/impeller/renderer/backend/gles/test/texture_gles_unittests.cc b/engine/src/flutter/impeller/renderer/backend/gles/test/texture_gles_unittests.cc index fd1797209a..4406a98214 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/test/texture_gles_unittests.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/test/texture_gles_unittests.cc @@ -65,4 +65,23 @@ TEST_P(TextureGLESTest, CanSetSyncFence) { ASSERT_FALSE(sync_fence.has_value()); } +TEST_P(TextureGLESTest, Binds2DTexture) { + TextureDescriptor desc; + desc.storage_mode = StorageMode::kDevicePrivate; + desc.size = {100, 100}; + desc.format = PixelFormat::kR8G8B8A8UNormInt; + desc.type = TextureType::kTexture2DMultisample; + desc.sample_count = SampleCount::kCount4; + + auto texture = GetContext()->GetResourceAllocator()->CreateTexture(desc); + + ASSERT_TRUE(texture); + + EXPECT_EQ( + TextureGLES::Cast(*texture).ComputeTypeForBinding(GL_READ_FRAMEBUFFER), + TextureGLES::Type::kTexture); + EXPECT_EQ(TextureGLES::Cast(*texture).ComputeTypeForBinding(GL_FRAMEBUFFER), + TextureGLES::Type::kTextureMultisampled); +} + } // namespace impeller::testing diff --git a/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc b/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc index e85aeb3772..39fe43e6b3 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc +++ b/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.cc @@ -392,6 +392,15 @@ static std::optional ToRenderBufferFormat(PixelFormat format) { FML_UNREACHABLE(); } +TextureGLES::Type TextureGLES::ComputeTypeForBinding(GLenum target) const { + // When binding to a GL_READ_FRAMEBUFFER, any multisampled + // textures must be bound as single sampled. + if (target == GL_READ_FRAMEBUFFER && type_ == Type::kTextureMultisampled) { + return Type::kTexture; + } + return type_; +} + void TextureGLES::InitializeContentsIfNecessary() const { if (!IsValid() || slices_initialized_[0]) { return; @@ -588,7 +597,7 @@ bool TextureGLES::SetAsFramebufferAttachment( } const auto& gl = reactor_->GetProcTable(); - switch (type_) { + switch (ComputeTypeForBinding(target)) { case Type::kTexture: gl.FramebufferTexture2D(target, // target ToAttachmentType(attachment_type), // attachment diff --git a/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.h b/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.h index 597fb726b2..5d7a18507a 100644 --- a/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.h +++ b/engine/src/flutter/impeller/renderer/backend/gles/texture_gles.h @@ -144,6 +144,9 @@ class TextureGLES final : public Texture, // Visible for testing. std::optional GetSyncFence() const; + // visible for testing + Type ComputeTypeForBinding(GLenum target) const; + private: std::shared_ptr reactor_; const Type type_;