Commit 6898b358 by Corentin Wallez Committed by Commit Bot

FramebufferGL: Fix blit workaround corner case

The SRGB blit workaround had to wrong assumptions: - SRGB blits can have a multisample source. - The woarkound is needed even when the filter is GL_LINEAR in the case where we are doing a RGB -> SRGB or RGB -> SRGB blit. BUG=angleproject:1492 BUG=chromium:658898 Change-Id: I1d89572565a4e23c1c97bdf985bb21a445e898b7 Reviewed-on: https://chromium-review.googlesource.com/409540Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent f58585cb
...@@ -283,59 +283,58 @@ Error FramebufferGL::blit(ContextImpl *context, ...@@ -283,59 +283,58 @@ Error FramebufferGL::blit(ContextImpl *context,
const Framebuffer *sourceFramebuffer = context->getGLState().getReadFramebuffer(); const Framebuffer *sourceFramebuffer = context->getGLState().getReadFramebuffer();
const Framebuffer *destFramebuffer = context->getGLState().getDrawFramebuffer(); const Framebuffer *destFramebuffer = context->getGLState().getDrawFramebuffer();
const FramebufferAttachment *colorReadAttachment = sourceFramebuffer->getReadColorbuffer();
GLsizei readAttachmentSamples = colorReadAttachment->getSamples();
bool needManualColorBlit = false; bool needManualColorBlit = false;
// The manual SRGB blit is only needed to perform correct linear interpolation. We don't // TODO(cwallez) when the filter is LINEAR and both source and destination are SRGB, we
// need to make sure there is SRGB conversion for NEAREST as the values will be copied. // could avoid doing a manual blit.
if (filter != GL_NEAREST)
// Prior to OpenGL 4.4 BlitFramebuffer (section 18.3.1 of GL 4.3 core profile) reads:
// When values are taken from the read buffer, no linearization is performed, even
// if the format of the buffer is SRGB.
// Starting from OpenGL 4.4 (section 18.3.1) it reads:
// When values are taken from the read buffer, if FRAMEBUFFER_SRGB is enabled and the
// value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment
// corresponding to the read buffer is SRGB, the red, green, and blue components are
// converted from the non-linear sRGB color space according [...].
{ {
bool sourceSRGB = colorReadAttachment != nullptr &&
colorReadAttachment->getColorEncoding() == GL_SRGB;
needManualColorBlit =
needManualColorBlit || (sourceSRGB && mFunctions->isAtMostGL(gl::Version(4, 3)));
}
// Prior to OpenGL 4.4 BlitFramebuffer (section 18.3.1 of GL 4.3 core profile) reads: // Prior to OpenGL 4.2 BlitFramebuffer (section 4.3.2 of GL 4.1 core profile) reads:
// When values are taken from the read buffer, no linearization is performed, even // Blit operations bypass the fragment pipeline. The only fragment operations which
// if the format of the buffer is SRGB. // affect a blit are the pixel ownership test and scissor test.
// Starting from OpenGL 4.4 (section 18.3.1) it reads: // Starting from OpenGL 4.2 (section 4.3.2) it reads:
// When values are taken from the read buffer, if FRAMEBUFFER_SRGB is enabled and the // When values are written to the draw buffers, blit operations bypass the fragment
// value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the framebuffer attachment // pipeline. The only fragment operations which affect a blit are the pixel ownership
// corresponding to the read buffer is SRGB, the red, green, and blue components are // test, the scissor test and sRGB conversion.
// converted from the non-linear sRGB color space according [...]. if (!needManualColorBlit)
{ {
const FramebufferAttachment *readAttachment = sourceFramebuffer->getReadColorbuffer(); bool destSRGB = false;
bool sourceSRGB = for (size_t i = 0; i < destFramebuffer->getDrawbufferStateCount(); ++i)
readAttachment != nullptr && readAttachment->getColorEncoding() == GL_SRGB;
needManualColorBlit =
needManualColorBlit || (sourceSRGB && mFunctions->isAtMostGL(gl::Version(4, 3)));
}
// Prior to OpenGL 4.2 BlitFramebuffer (section 4.3.2 of GL 4.1 core profile) reads:
// Blit operations bypass the fragment pipeline. The only fragment operations which
// affect a blit are the pixel ownership test and scissor test.
// Starting from OpenGL 4.2 (section 4.3.2) it reads:
// When values are written to the draw buffers, blit operations bypass the fragment
// pipeline. The only fragment operations which affect a blit are the pixel ownership
// test, the scissor test and sRGB conversion.
if (!needManualColorBlit)
{ {
bool destSRGB = false; const FramebufferAttachment *attachment = destFramebuffer->getDrawBuffer(i);
for (size_t i = 0; i < destFramebuffer->getDrawbufferStateCount(); ++i) if (attachment && attachment->getColorEncoding() == GL_SRGB)
{ {
const FramebufferAttachment *attachment = destFramebuffer->getDrawBuffer(i); destSRGB = true;
if (attachment && attachment->getColorEncoding() == GL_SRGB) break;
{
destSRGB = true;
break;
}
} }
needManualColorBlit =
needManualColorBlit || (destSRGB && mFunctions->isAtMostGL(gl::Version(4, 1)));
} }
needManualColorBlit =
needManualColorBlit || (destSRGB && mFunctions->isAtMostGL(gl::Version(4, 1)));
} }
// Enable FRAMEBUFFER_SRGB if needed // Enable FRAMEBUFFER_SRGB if needed
mStateManager->setFramebufferSRGBEnabledForFramebuffer(true, this); mStateManager->setFramebufferSRGBEnabledForFramebuffer(true, this);
GLenum blitMask = mask; GLenum blitMask = mask;
if (needManualColorBlit && (mask & GL_COLOR_BUFFER_BIT)) if (needManualColorBlit && (mask & GL_COLOR_BUFFER_BIT) && readAttachmentSamples <= 1)
{ {
ANGLE_TRY(mBlitter->blitColorBufferWithShader(sourceFramebuffer, destFramebuffer, ANGLE_TRY(mBlitter->blitColorBufferWithShader(sourceFramebuffer, destFramebuffer,
sourceArea, destArea, filter)); sourceArea, destArea, filter));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment