Call getNearestSamples() in Framebuffer::setAttachment()

The app jp.garud.ssimulator uses the same sample count of '2' for both
glRenderbufferStorageMultisampleEXT() and
glFramebufferTexture2DMultisampleEXT(). However, when
glRenderbufferStorageMultisampleEXT() is called,
Renderbuffer::setStorageMultisample() calls
TextureCaps::getNearestSamples() which rounds up the sample count from
'2' to '4'.   Later, when the app tries to draw with the framebuffer,
an error is generated by ANGLE:

Framebuffer is incomplete: Attachments have different sample counts.

The fix is to also call TextureCaps::getNearestSamples() in
Framebuffer::setAttachment() to make sure the sample count passed
into glFramebufferTexture2DMultisampleEXT() is also rounded up to
match the renderbuffer.

Bug: angleproject:6183
Test: MultisampledRenderToTextureTest.FramebufferCompletenessSmallSampleCount
Change-Id: I58be9986077257f4767f2e528c2f87e496d9d774
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3036254
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Tim Van Patten <timvp@google.com>
This commit is contained in:
Tim Van Patten 2021-07-16 14:57:13 -06:00 коммит произвёл Angle LUCI CQ
Родитель ab197a2bd3
Коммит 9ddaa68604
7 изменённых файлов: 63 добавлений и 9 удалений

Просмотреть файл

@ -1793,8 +1793,19 @@ void Framebuffer::setAttachment(const Context *context,
GLsizei numViews,
GLuint baseViewIndex,
bool isMultiview,
GLsizei samples)
GLsizei samplesIn)
{
GLsizei samples = samplesIn;
// Match the sample count to the attachment's sample count.
if (resource)
{
const InternalFormat *info = resource->getAttachmentFormat(binding, textureIndex).info;
ASSERT(info);
GLenum internalformat = info->internalFormat;
const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
samples = formatCaps.getNearestSamples(samples);
}
// Context may be null in unit tests.
if (!context || !context->isWebGL1())
{

Просмотреть файл

@ -450,7 +450,7 @@ class Framebuffer final : public angle::ObserverInterface,
GLsizei numViews,
GLuint baseViewIndex,
bool isMultiview,
GLsizei samples);
GLsizei samplesIn);
void commitWebGL1DepthStencilIfConsistent(const Context *context,
GLsizei numViews,
GLuint baseViewIndex,

Просмотреть файл

@ -133,7 +133,7 @@ angle::Result Renderbuffer::setStorage(const Context *context,
}
angle::Result Renderbuffer::setStorageMultisample(const Context *context,
GLsizei samples,
GLsizei samplesIn,
GLenum internalformat,
GLsizei width,
GLsizei height,
@ -141,9 +141,9 @@ angle::Result Renderbuffer::setStorageMultisample(const Context *context,
{
ANGLE_TRY(orphanImages(context));
// Potentially adjust "samples" to a supported value
// Potentially adjust "samplesIn" to a supported value
const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
samples = formatCaps.getNearestSamples(samples);
GLsizei samples = formatCaps.getNearestSamples(samplesIn);
ANGLE_TRY(mImplementation->setStorageMultisample(context, samples, internalformat, width,
height, mode));

Просмотреть файл

@ -83,7 +83,7 @@ class Renderbuffer final : public RefCountObject<RenderbufferID>,
GLsizei width,
GLsizei height);
angle::Result setStorageMultisample(const Context *context,
GLsizei samples,
GLsizei samplesIn,
GLenum internalformat,
GLsizei width,
GLsizei height,

Просмотреть файл

@ -1590,7 +1590,7 @@ angle::Result Texture::setImageExternal(Context *context,
angle::Result Texture::setStorageMultisample(Context *context,
TextureType type,
GLsizei samples,
GLsizei samplesIn,
GLint internalFormat,
const Extents &size,
bool fixedSampleLocations)
@ -1603,7 +1603,7 @@ angle::Result Texture::setStorageMultisample(Context *context,
// Potentially adjust "samples" to a supported value
const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
samples = formatCaps.getNearestSamples(samples);
GLsizei samples = formatCaps.getNearestSamples(samplesIn);
mState.mImmutableFormat = true;
mState.mImmutableLevels = static_cast<GLuint>(1);

Просмотреть файл

@ -465,7 +465,7 @@ class Texture final : public RefCountObject<TextureID>,
angle::Result setStorageMultisample(Context *context,
TextureType type,
GLsizei samples,
GLsizei samplesIn,
GLint internalformat,
const Extents &size,
bool fixedSampleLocations);

Просмотреть файл

@ -484,6 +484,49 @@ TEST_P(MultisampledRenderToTextureTest, FramebufferCompleteness)
}
}
// Checking for framebuffer completeness using extension methods.
TEST_P(MultisampledRenderToTextureTest, FramebufferCompletenessSmallSampleCount)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
// Test failure introduced by Apple's changes (anglebug.com/5505)
ANGLE_SKIP_TEST_IF(IsMetal() && IsAMD());
// A sample count of '2' can be rounded up to '4' on some systems (e.g., ARM+Android).
GLsizei samples = 2;
// Checking that Renderbuffer and texture2d having different number of samples results
// in a FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
GLTexture texture;
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
ASSERT_GL_NO_ERROR();
// Texture attachment for color attachment 0. Framebuffer should be complete.
GLFramebuffer FBO;
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
texture, 0, samples);
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
// Depth/stencil renderbuffer, potentially with a different sample count.
GLRenderbuffer dsRenderbuffer;
glBindRenderbuffer(GL_RENDERBUFFER, dsRenderbuffer);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, 64, 64);
ASSERT_GL_NO_ERROR();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dsRenderbuffer);
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
// Color renderbuffer for color attachment 0.
GLRenderbuffer colorRenderbuffer;
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGBA4, 64, 64);
ASSERT_GL_NO_ERROR();
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
colorRenderbuffer);
EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
}
void MultisampledRenderToTextureTest::createAndAttachColorAttachment(
bool useRenderbuffer,
GLsizei size,