Commit 95ba174e by Frank Henigman Committed by Commit Bot

Clip TextureD3D_2D::copyImage to framebuffer.

WebGL CopyTexImage needs to zero the part of the texture corresponding to area outside the framebuffer, so we zero the whole texture then clip the read area. The clipping also avoids problems with code lower down that isn't prepared for read areas not entirely within the framebuffer. Enable corresponding test. BUG=angleproject:1815 Change-Id: Ia7e0243ca72fa7c8f5bacda4d2022061d6a6d4f0 Reviewed-on: https://chromium-review.googlesource.com/551056Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Frank Henigman <fjhenigman@chromium.org>
parent 6cad5667
...@@ -1035,21 +1035,53 @@ gl::Error TextureD3D_2D::setCompressedSubImage(const gl::Context *context, ...@@ -1035,21 +1035,53 @@ gl::Error TextureD3D_2D::setCompressedSubImage(const gl::Context *context,
gl::Error TextureD3D_2D::copyImage(const gl::Context *context, gl::Error TextureD3D_2D::copyImage(const gl::Context *context,
GLenum target, GLenum target,
size_t imageLevel, size_t imageLevel,
const gl::Rectangle &sourceArea, const gl::Rectangle &origSourceArea,
GLenum internalFormat, GLenum internalFormat,
const gl::Framebuffer *source) const gl::Framebuffer *source)
{ {
ASSERT(target == GL_TEXTURE_2D); ASSERT(target == GL_TEXTURE_2D);
GLint level = static_cast<GLint>(imageLevel); GLint level = static_cast<GLint>(imageLevel);
const gl::InternalFormat &internalFormatInfo = const gl::InternalFormat &internalFormatInfo =
gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, gl::Extents sourceExtents(origSourceArea.width, origSourceArea.height, 1);
gl::Extents(sourceArea.width, sourceArea.height, 1), ANGLE_TRY(redefineImage(context, level, internalFormatInfo.sizedInternalFormat, sourceExtents,
mRenderer->isRobustResourceInitEnabled())); mRenderer->isRobustResourceInitEnabled()));
gl::Extents fbSize = source->getReadColorbuffer()->getSize();
// Does the read area extend beyond the framebuffer?
bool outside = origSourceArea.x < 0 || origSourceArea.y < 0 ||
origSourceArea.x + origSourceArea.width > fbSize.width ||
origSourceArea.y + origSourceArea.height > fbSize.height;
// In WebGL mode we need to zero the texture outside the framebuffer.
// If we have robust resource init, it was already zeroed by redefineImage() above, otherwise
// zero it explicitly.
// TODO(fjhenigman): When robust resource is fully implemented look into making it a
// prerequisite for WebGL and deleting this code.
if (outside && context->getExtensions().webglCompatibility &&
!mRenderer->isRobustResourceInitEnabled())
{
angle::MemoryBuffer *zero;
ANGLE_TRY(context->getScratchBuffer(
origSourceArea.width * origSourceArea.height * internalFormatInfo.pixelBytes, &zero));
zero->fill(0);
setImage(context, target, imageLevel, internalFormat, sourceExtents,
internalFormatInfo.format, internalFormatInfo.type, gl::PixelUnpackState(1, 0),
zero->data());
}
gl::Rectangle sourceArea;
if (!ClipRectangle(origSourceArea, gl::Rectangle(0, 0, fbSize.width, fbSize.height),
&sourceArea))
{
// Empty source area, nothing to do.
return gl::NoError();
}
gl::ImageIndex index = gl::ImageIndex::Make2D(level); gl::ImageIndex index = gl::ImageIndex::Make2D(level);
gl::Offset destOffset(0, 0, 0); gl::Offset destOffset(sourceArea.x - origSourceArea.x, sourceArea.y - origSourceArea.y, 0);
// If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders, // If the zero max LOD workaround is active, then we can't sample from individual layers of the framebuffer in shaders,
// so we should use the non-rendering copy path. // so we should use the non-rendering copy path.
......
...@@ -276,7 +276,10 @@ TEST_P(WebGLReadOutsideFramebufferTest, CopyTexSubImage2D) ...@@ -276,7 +276,10 @@ TEST_P(WebGLReadOutsideFramebufferTest, CopyTexSubImage2D)
// Check that copyTexImage2D sets (0,0,0,0) for pixels outside the framebuffer. // Check that copyTexImage2D sets (0,0,0,0) for pixels outside the framebuffer.
TEST_P(WebGLReadOutsideFramebufferTest, CopyTexImage2D) TEST_P(WebGLReadOutsideFramebufferTest, CopyTexImage2D)
{ {
// Main(&WebGLReadOutsideFramebufferTest::TestCopyTexImage2D, true); if (IsD3DSM3() || IsD3D11())
{
Main(&WebGLReadOutsideFramebufferTest::TestCopyTexImage2D, true);
}
} }
ANGLE_INSTANTIATE_TEST(WebGLReadOutsideFramebufferTest, ANGLE_INSTANTIATE_TEST(WebGLReadOutsideFramebufferTest,
......
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