Commit 05c729f3 by Jamie Madill

Pass unpack buffer as explicit parameter to texSubImage.

This allows us to override it in the incomplete texture init. Any back-end that used incomplete textures was vulnerable to a bug where the unpack buffer would be used to initialize the incomplete texture. Cherry-picked to the chromium/3538 branch cleanly. Bug: chromium:880906 Change-Id: Iead2a8c57674e8962915902d6d5896f44fe8ca88 Reviewed-on: https://chromium-review.googlesource.com/1227033Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 5fdc38cf
......@@ -3986,8 +3986,11 @@ void Context::texSubImage2D(TextureTarget target,
Box area(xoffset, yoffset, 0, width, height, 1);
Texture *texture = getTargetTexture(TextureTargetToType(target));
handleError(texture->setSubImage(this, mGLState.getUnpackState(), target, level, area, format,
type, static_cast<const uint8_t *>(pixels)));
gl::Buffer *unpackBuffer = mGLState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
handleError(texture->setSubImage(this, mGLState.getUnpackState(), unpackBuffer, target, level,
area, format, type, static_cast<const uint8_t *>(pixels)));
}
void Context::texSubImage2DRobust(TextureTarget target,
......@@ -4026,7 +4029,10 @@ void Context::texSubImage3D(TextureType target,
Box area(xoffset, yoffset, zoffset, width, height, depth);
Texture *texture = getTargetTexture(target);
handleError(texture->setSubImage(this, mGLState.getUnpackState(),
gl::Buffer *unpackBuffer = mGLState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
handleError(texture->setSubImage(this, mGLState.getUnpackState(), unpackBuffer,
NonCubeTextureTypeToTarget(target), level, area, format, type,
static_cast<const uint8_t *>(pixels)));
}
......
......@@ -970,6 +970,7 @@ Error Texture::setImage(const Context *context,
Error Texture::setSubImage(const Context *context,
const PixelUnpackState &unpackState,
Buffer *unpackBuffer,
TextureTarget target,
GLint level,
const Box &area,
......@@ -983,7 +984,8 @@ Error Texture::setSubImage(const Context *context,
ImageIndex index = ImageIndex::MakeFromTarget(target, level);
ANGLE_TRY(mTexture->setSubImage(context, index, area, format, type, unpackState, pixels));
ANGLE_TRY(mTexture->setSubImage(context, index, area, format, type, unpackState, unpackBuffer,
pixels));
ANGLE_TRY(handleMipmapGenerationHint(context, level));
......
......@@ -288,6 +288,7 @@ class Texture final : public RefCountObject, public egl::ImageSibling, public La
const uint8_t *pixels);
Error setSubImage(const Context *context,
const PixelUnpackState &unpackState,
Buffer *unpackBuffer,
TextureTarget target,
GLint level,
const Box &area,
......
......@@ -62,6 +62,7 @@ class TextureImpl : public FramebufferAttachmentObjectImpl
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) = 0;
virtual gl::Error setCompressedImage(const gl::Context *context,
......
......@@ -30,13 +30,14 @@ class MockTextureImpl : public TextureImpl
GLenum,
const gl::PixelUnpackState &,
const uint8_t *));
MOCK_METHOD7(setSubImage,
MOCK_METHOD8(setSubImage,
gl::Error(const gl::Context *,
const gl::ImageIndex &,
const gl::Box &,
GLenum,
GLenum,
const gl::PixelUnpackState &,
gl::Buffer *,
const uint8_t *));
MOCK_METHOD7(setCompressedImage,
gl::Error(const gl::Context *,
......
......@@ -258,13 +258,12 @@ angle::Result TextureD3D::subImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels,
ptrdiff_t layerOffset)
{
// CPU readback & copy where direct GPU copy is not supported
const uint8_t *pixelData = nullptr;
gl::Buffer *unpackBuffer =
context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
ANGLE_TRY(GetUnpackPointer(context, unpack, unpackBuffer, pixels, layerOffset, &pixelData));
if (pixelData != nullptr)
......@@ -883,12 +882,11 @@ gl::Error TextureD3D_2D::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
ASSERT(index.getTarget() == gl::TextureTarget::_2D && area.depth == 1 && area.z == 0);
gl::Buffer *unpackBuffer =
context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
GLenum mipFormat = getInternalFormat(index.getLevelIndex());
if (isFastUnpackable(unpackBuffer, mipFormat) && isLevelComplete(index.getLevelIndex()))
{
......@@ -900,7 +898,8 @@ gl::Error TextureD3D_2D::setSubImage(const gl::Context *context,
}
else
{
return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0);
return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer,
pixels, 0);
}
}
......@@ -1648,10 +1647,12 @@ gl::Error TextureD3D_Cube::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
ASSERT(area.depth == 1 && area.z == 0);
return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0);
return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer, pixels,
0);
}
gl::Error TextureD3D_Cube::setCompressedImage(const gl::Context *context,
......@@ -2404,13 +2405,12 @@ gl::Error TextureD3D_3D::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
ASSERT(index.getTarget() == gl::TextureTarget::_3D);
// Attempt a fast gpu copy of the pixel data to the surface if the app bound an unpack buffer
gl::Buffer *unpackBuffer =
context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
GLenum mipFormat = getInternalFormat(index.getLevelIndex());
if (isFastUnpackable(unpackBuffer, mipFormat) && isLevelComplete(index.getLevelIndex()))
{
......@@ -2422,7 +2422,8 @@ gl::Error TextureD3D_3D::setSubImage(const gl::Context *context,
}
else
{
return TextureD3D::subImage(context, index, area, format, type, unpack, pixels, 0);
return TextureD3D::subImage(context, index, area, format, type, unpack, unpackBuffer,
pixels, 0);
}
}
......@@ -2932,6 +2933,7 @@ gl::Error TextureD3D_2DArray::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
ASSERT(index.getTarget() == gl::TextureTarget::_2DArray);
......@@ -2950,8 +2952,8 @@ gl::Error TextureD3D_2DArray::setSubImage(const gl::Context *context,
gl::Box layerArea(area.x, area.y, 0, area.width, area.height, 1);
gl::ImageIndex layerIndex = gl::ImageIndex::Make2DArray(index.getLevelIndex(), layer);
ANGLE_TRY(TextureD3D::subImage(context, layerIndex, layerArea, format, type, unpack, pixels,
layerOffset));
ANGLE_TRY(TextureD3D::subImage(context, layerIndex, layerArea, format, type, unpack,
unpackBuffer, pixels, layerOffset));
}
return gl::NoError();
......@@ -3484,6 +3486,7 @@ gl::Error TextureD3DImmutableBase::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
UNREACHABLE();
......
......@@ -114,6 +114,7 @@ class TextureD3D : public TextureImpl
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels,
ptrdiff_t layerOffset);
angle::Result setCompressedImageImpl(const gl::Context *context,
......@@ -216,6 +217,7 @@ class TextureD3D_2D : public TextureD3D
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......@@ -344,6 +346,7 @@ class TextureD3D_Cube : public TextureD3D
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......@@ -473,6 +476,7 @@ class TextureD3D_3D : public TextureD3D
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......@@ -581,6 +585,7 @@ class TextureD3D_2DArray : public TextureD3D
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......@@ -685,6 +690,7 @@ class TextureD3DImmutableBase : public TextureD3D
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......
......@@ -257,6 +257,7 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
ASSERT(TextureTargetToType(index.getTarget()) == getType());
......@@ -265,9 +266,6 @@ gl::Error TextureGL::setSubImage(const gl::Context *context,
StateManagerGL *stateManager = GetStateManagerGL(context);
const WorkaroundsGL &workarounds = GetWorkaroundsGL(context);
const gl::Buffer *unpackBuffer =
context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack);
nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(functions, workarounds, format, type);
......
......@@ -75,6 +75,7 @@ class TextureGL : public TextureImpl
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......
......@@ -42,6 +42,7 @@ gl::Error TextureNULL::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
return gl::NoError();
......
......@@ -35,6 +35,7 @@ class TextureNULL : public TextureImpl
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......
......@@ -446,8 +446,8 @@ gl::Error IncompleteTextureSet::getIncompleteTexture(
{
for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
{
ANGLE_TRY(
t->setSubImage(context, unpack, face, 0, area, GL_RGBA, GL_UNSIGNED_BYTE, color));
ANGLE_TRY(t->setSubImage(context, unpack, nullptr, face, 0, area, GL_RGBA,
GL_UNSIGNED_BYTE, color));
}
}
else if (type == gl::TextureType::_2DMultisample)
......@@ -457,8 +457,9 @@ gl::Error IncompleteTextureSet::getIncompleteTexture(
}
else
{
ANGLE_TRY(t->setSubImage(context, unpack, gl::NonCubeTextureTypeToTarget(createType), 0,
area, GL_RGBA, GL_UNSIGNED_BYTE, color));
ANGLE_TRY(t->setSubImage(context, unpack, nullptr,
gl::NonCubeTextureTypeToTarget(createType), 0, area, GL_RGBA,
GL_UNSIGNED_BYTE, color));
}
ANGLE_TRY(t->syncState(context));
......
......@@ -491,6 +491,7 @@ gl::Error TextureVk::setSubImage(const gl::Context *context,
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels)
{
ContextVk *contextVk = vk::GetImpl(context);
......
......@@ -104,6 +104,7 @@ class TextureVk : public TextureImpl, public vk::CommandGraphResource
GLenum format,
GLenum type,
const gl::PixelUnpackState &unpack,
gl::Buffer *unpackBuffer,
const uint8_t *pixels) override;
gl::Error setCompressedImage(const gl::Context *context,
......
......@@ -69,6 +69,20 @@ class IncompleteTextureTest : public ANGLETest
GLint mTextureUniformLocation;
};
class IncompleteTextureTestES3 : public ANGLETest
{
protected:
IncompleteTextureTestES3()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
};
class IncompleteTextureTestES31 : public ANGLETest
{
protected:
......@@ -163,6 +177,21 @@ TEST_P(IncompleteTextureTest, UpdateTexture)
GLColor::green);
}
// Tests that incomplete textures don't get initialized with the unpack buffer contents.
TEST_P(IncompleteTextureTestES3, UnpackBufferBound)
{
std::vector<GLColor> red(16, GLColor::red);
GLBuffer unpackBuffer;
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, red.size() * sizeof(GLColor), red.data(), GL_STATIC_DRAW);
draw2DTexturedQuad(0.5f, 1.0f, true);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
}
// Tests that the incomplete multisample texture has the correct alpha value.
TEST_P(IncompleteTextureTestES31, MultisampleTexture)
{
......@@ -208,5 +237,5 @@ ANGLE_INSTANTIATE_TEST(IncompleteTextureTest,
ES2_OPENGL(),
ES2_OPENGLES(),
ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(IncompleteTextureTestES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
ANGLE_INSTANTIATE_TEST(IncompleteTextureTestES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
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