Commit 13e31bb0 by Geoff Lang Committed by Commit Bot

GL: Check framebuffer completeness before running blit shaders.

Cube map destination textures may not be complete until all faces have been initialized. BUG=693090 Change-Id: I19816c9def3b9663491397cded5d24ca808a3f78 Reviewed-on: https://chromium-review.googlesource.com/982393Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 7b7d2e6a
...@@ -514,7 +514,7 @@ gl::Error BlitGL::blitColorBufferWithShader(const gl::Framebuffer *source, ...@@ -514,7 +514,7 @@ gl::Error BlitGL::blitColorBufferWithShader(const gl::Framebuffer *source,
return gl::NoError(); return gl::NoError();
} }
gl::Error BlitGL::copySubTexture(const gl::Context *context, gl::ErrorOrResult<bool> BlitGL::copySubTexture(const gl::Context *context,
TextureGL *source, TextureGL *source,
size_t sourceLevel, size_t sourceLevel,
GLenum sourceComponentType, GLenum sourceComponentType,
...@@ -534,6 +534,17 @@ gl::Error BlitGL::copySubTexture(const gl::Context *context, ...@@ -534,6 +534,17 @@ gl::Error BlitGL::copySubTexture(const gl::Context *context,
ASSERT(source->getType() == gl::TextureType::_2D); ASSERT(source->getType() == gl::TextureType::_2D);
ANGLE_TRY(initializeResources()); ANGLE_TRY(initializeResources());
// Make sure the destination texture can be rendered to before setting anything else up. Some
// cube maps may not be renderable until all faces have been filled.
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ToGLenum(destTarget),
dest->getTextureID(), static_cast<GLint>(destLevel));
GLenum status = mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
return false;
}
BlitProgramType blitProgramType = getBlitProgramType(sourceComponentType, destComponentType); BlitProgramType blitProgramType = getBlitProgramType(sourceComponentType, destComponentType);
BlitProgram *blitProgram = nullptr; BlitProgram *blitProgram = nullptr;
ANGLE_TRY(getBlitProgram(blitProgramType, &blitProgram)); ANGLE_TRY(getBlitProgram(blitProgramType, &blitProgram));
...@@ -598,14 +609,10 @@ gl::Error BlitGL::copySubTexture(const gl::Context *context, ...@@ -598,14 +609,10 @@ gl::Error BlitGL::copySubTexture(const gl::Context *context,
mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, unpackUnmultiplyAlpha); mFunctions->uniform1i(blitProgram->unMultiplyAlphaLocation, unpackUnmultiplyAlpha);
} }
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, ToGLenum(destTarget),
dest->getTextureID(), static_cast<GLint>(destLevel));
mStateManager->bindVertexArray(mVAO, 0); mStateManager->bindVertexArray(mVAO, 0);
mFunctions->drawArrays(GL_TRIANGLES, 0, 3); mFunctions->drawArrays(GL_TRIANGLES, 0, 3);
return gl::NoError(); return true;
} }
gl::Error BlitGL::copySubTextureCPUReadback(const gl::Context *context, gl::Error BlitGL::copySubTextureCPUReadback(const gl::Context *context,
...@@ -686,7 +693,7 @@ gl::Error BlitGL::copySubTextureCPUReadback(const gl::Context *context, ...@@ -686,7 +693,7 @@ gl::Error BlitGL::copySubTextureCPUReadback(const gl::Context *context,
return gl::NoError(); return gl::NoError();
} }
gl::Error BlitGL::copyTexSubImage(TextureGL *source, gl::ErrorOrResult<bool> BlitGL::copyTexSubImage(TextureGL *source,
size_t sourceLevel, size_t sourceLevel,
TextureGL *dest, TextureGL *dest,
gl::TextureTarget destTarget, gl::TextureTarget destTarget,
...@@ -696,9 +703,15 @@ gl::Error BlitGL::copyTexSubImage(TextureGL *source, ...@@ -696,9 +703,15 @@ gl::Error BlitGL::copyTexSubImage(TextureGL *source,
{ {
ANGLE_TRY(initializeResources()); ANGLE_TRY(initializeResources());
// Make sure the source texture can create a complete framebuffer before continuing.
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO); mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mScratchFBO);
mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mFunctions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
source->getTextureID(), static_cast<GLint>(sourceLevel)); source->getTextureID(), static_cast<GLint>(sourceLevel));
GLenum status = mFunctions->checkFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
return false;
}
mStateManager->bindTexture(dest->getType(), dest->getTextureID()); mStateManager->bindTexture(dest->getType(), dest->getTextureID());
...@@ -706,7 +719,7 @@ gl::Error BlitGL::copyTexSubImage(TextureGL *source, ...@@ -706,7 +719,7 @@ gl::Error BlitGL::copyTexSubImage(TextureGL *source,
destOffset.y, sourceArea.x, sourceArea.y, sourceArea.width, destOffset.y, sourceArea.x, sourceArea.y, sourceArea.width,
sourceArea.height); sourceArea.height);
return gl::NoError(); return true;
} }
gl::ErrorOrResult<bool> BlitGL::clearRenderableTexture(TextureGL *source, gl::ErrorOrResult<bool> BlitGL::clearRenderableTexture(TextureGL *source,
......
...@@ -66,7 +66,7 @@ class BlitGL : angle::NonCopyable ...@@ -66,7 +66,7 @@ class BlitGL : angle::NonCopyable
const gl::Rectangle &destArea, const gl::Rectangle &destArea,
GLenum filter); GLenum filter);
gl::Error copySubTexture(const gl::Context *context, gl::ErrorOrResult<bool> copySubTexture(const gl::Context *context,
TextureGL *source, TextureGL *source,
size_t sourceLevel, size_t sourceLevel,
GLenum sourceComponentType, GLenum sourceComponentType,
...@@ -98,7 +98,7 @@ class BlitGL : angle::NonCopyable ...@@ -98,7 +98,7 @@ class BlitGL : angle::NonCopyable
bool unpackPremultiplyAlpha, bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha); bool unpackUnmultiplyAlpha);
gl::Error copyTexSubImage(TextureGL *source, gl::ErrorOrResult<bool> copyTexSubImage(TextureGL *source,
size_t sourceLevel, size_t sourceLevel,
TextureGL *dest, TextureGL *dest,
gl::TextureTarget destTarget, gl::TextureTarget destTarget,
......
...@@ -771,8 +771,14 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -771,8 +771,14 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
sourceFormatContainSupersetOfDestFormat && sourceComponentType == destComponentType && sourceFormatContainSupersetOfDestFormat && sourceComponentType == destComponentType &&
!destSRGB) !destSRGB)
{ {
return mBlitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level, sourceArea, bool copySucceded = false;
destOffset); ANGLE_TRY_RESULT(mBlitter->copyTexSubImage(sourceGL, sourceLevel, this, target, level,
sourceArea, destOffset),
copySucceded);
if (copySucceded)
{
return gl::NoError();
}
} }
// Check if the destination is renderable and copy on the GPU // Check if the destination is renderable and copy on the GPU
...@@ -780,11 +786,17 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context, ...@@ -780,11 +786,17 @@ gl::Error TextureGL::copySubTextureHelper(const gl::Context *context,
if (!destSRGB && nativegl::SupportsNativeRendering(mFunctions, getType(), if (!destSRGB && nativegl::SupportsNativeRendering(mFunctions, getType(),
destLevelInfo.nativeInternalFormat)) destLevelInfo.nativeInternalFormat))
{ {
return mBlitter->copySubTexture(context, sourceGL, sourceLevel, sourceComponentType, this, bool copySucceded = false;
target, level, destComponentType, sourceImageDesc.size, ANGLE_TRY_RESULT(mBlitter->copySubTexture(
sourceArea, destOffset, needsLumaWorkaround, context, sourceGL, sourceLevel, sourceComponentType, this, target,
sourceLevelInfo.sourceFormat, unpackFlipY, level, destComponentType, sourceImageDesc.size, sourceArea, destOffset,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha); needsLumaWorkaround, sourceLevelInfo.sourceFormat, unpackFlipY,
unpackPremultiplyAlpha, unpackUnmultiplyAlpha),
copySucceded);
if (copySucceded)
{
return gl::NoError();
}
} }
// Fall back to CPU-readback // Fall back to CPU-readback
......
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