Commit f2a06035 by Geoff Lang Committed by Commit Bot

Force-release images on redefine when robust resource init is enabled.

If the user repreatedly calls glTexImage with null data and the same size, it is expected that the texture would re-fill itself with zero'd data. TextureD3D and ImageD3D would no-op these calls when the texture is already the right size. TEST=conformance2/rendering/blitframebuffer-filter-outofbounds BUG=angleproject:1635 Change-Id: I810b15922759a4acfc0ef7da198f068b81e9efc4 Reviewed-on: https://chromium-review.googlesource.com/524436 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent 93a540fc
...@@ -873,7 +873,8 @@ gl::Error TextureD3D_2D::setImage(const gl::Context *context, ...@@ -873,7 +873,8 @@ gl::Error TextureD3D_2D::setImage(const gl::Context *context,
bool fastUnpacked = false; bool fastUnpacked = false;
GLint level = static_cast<GLint>(imageLevel); GLint level = static_cast<GLint>(imageLevel);
redefineImage(level, internalFormatInfo.sizedInternalFormat, size, false); redefineImage(level, internalFormatInfo.sizedInternalFormat, size,
mRenderer->isRobustResourceInitEnabled());
gl::ImageIndex index = gl::ImageIndex::Make2D(level); gl::ImageIndex index = gl::ImageIndex::Make2D(level);
...@@ -943,7 +944,7 @@ gl::Error TextureD3D_2D::setCompressedImage(const gl::Context *context, ...@@ -943,7 +944,7 @@ gl::Error TextureD3D_2D::setCompressedImage(const gl::Context *context,
GLint level = static_cast<GLint>(imageLevel); GLint level = static_cast<GLint>(imageLevel);
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly // compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, internalFormat, size, false); redefineImage(level, internalFormat, size, mRenderer->isRobustResourceInitEnabled());
return setCompressedImageImpl(gl::ImageIndex::Make2D(level), unpack, pixels, 0); return setCompressedImageImpl(gl::ImageIndex::Make2D(level), unpack, pixels, 0);
} }
...@@ -978,7 +979,8 @@ gl::Error TextureD3D_2D::copyImage(const gl::Context *context, ...@@ -978,7 +979,8 @@ gl::Error TextureD3D_2D::copyImage(const gl::Context *context,
const gl::InternalFormat &internalFormatInfo = const gl::InternalFormat &internalFormatInfo =
gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE); gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
redefineImage(level, internalFormatInfo.sizedInternalFormat, redefineImage(level, internalFormatInfo.sizedInternalFormat,
gl::Extents(sourceArea.width, sourceArea.height, 1), false); gl::Extents(sourceArea.width, sourceArea.height, 1),
mRenderer->isRobustResourceInitEnabled());
gl::ImageIndex index = gl::ImageIndex::Make2D(level); gl::ImageIndex index = gl::ImageIndex::Make2D(level);
gl::Offset destOffset(0, 0, 0); gl::Offset destOffset(0, 0, 0);
...@@ -1481,10 +1483,9 @@ void TextureD3D_2D::redefineImage(size_t level, ...@@ -1481,10 +1483,9 @@ void TextureD3D_2D::redefineImage(size_t level,
mImageArray[0]->copyFromTexStorage(gl::ImageIndex::Make2D(0), mTexStorage); mImageArray[0]->copyFromTexStorage(gl::ImageIndex::Make2D(0), mTexStorage);
} }
if ((level >= storageLevels && storageLevels != 0) || if (forceRelease || (level >= storageLevels && storageLevels != 0) ||
size.width != storageWidth || size.width != storageWidth || size.height != storageHeight ||
size.height != storageHeight || internalformat != storageFormat) // Discard mismatched storage
internalformat != storageFormat) // Discard mismatched storage
{ {
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
markAllImagesDirty(); markAllImagesDirty();
...@@ -2152,16 +2153,17 @@ void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalf ...@@ -2152,16 +2153,17 @@ void TextureD3D_Cube::redefineImage(int faceIndex, GLint level, GLenum internalf
const int storageHeight = std::max(1, getLevelZeroHeight() >> level); const int storageHeight = std::max(1, getLevelZeroHeight() >> level);
const GLenum storageFormat = getBaseLevelInternalFormat(); const GLenum storageFormat = getBaseLevelInternalFormat();
mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalformat, size, false); bool forceRelease = mRenderer->isRobustResourceInitEnabled();
mImageArray[faceIndex][level]->redefine(GL_TEXTURE_CUBE_MAP, internalformat, size,
forceRelease);
if (mTexStorage) if (mTexStorage)
{ {
const int storageLevels = mTexStorage->getLevelCount(); const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) || if (forceRelease || (level >= storageLevels && storageLevels != 0) ||
size.width != storageWidth || size.width != storageWidth || size.height != storageHeight ||
size.height != storageHeight || internalformat != storageFormat) // Discard mismatched storage
internalformat != storageFormat) // Discard mismatched storage
{ {
markAllImagesDirty(); markAllImagesDirty();
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
...@@ -2686,17 +2688,17 @@ void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, const gl:: ...@@ -2686,17 +2688,17 @@ void TextureD3D_3D::redefineImage(GLint level, GLenum internalformat, const gl::
const int storageDepth = std::max(1, getLevelZeroDepth() >> level); const int storageDepth = std::max(1, getLevelZeroDepth() >> level);
const GLenum storageFormat = getBaseLevelInternalFormat(); const GLenum storageFormat = getBaseLevelInternalFormat();
mImageArray[level]->redefine(GL_TEXTURE_3D, internalformat, size, false); bool forceRelease = mRenderer->isRobustResourceInitEnabled();
mImageArray[level]->redefine(GL_TEXTURE_3D, internalformat, size, forceRelease);
if (mTexStorage) if (mTexStorage)
{ {
const int storageLevels = mTexStorage->getLevelCount(); const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) || if (forceRelease || (level >= storageLevels && storageLevels != 0) ||
size.width != storageWidth || size.width != storageWidth || size.height != storageHeight ||
size.height != storageHeight ||
size.depth != storageDepth || size.depth != storageDepth ||
internalformat != storageFormat) // Discard mismatched storage internalformat != storageFormat) // Discard mismatched storage
{ {
markAllImagesDirty(); markAllImagesDirty();
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
...@@ -3278,12 +3280,15 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const ...@@ -3278,12 +3280,15 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const
} }
} }
bool forceRelease = mRenderer->isRobustResourceInitEnabled();
if (size.depth > 0) if (size.depth > 0)
{ {
for (int layer = 0; layer < mLayerCounts[level]; layer++) for (int layer = 0; layer < mLayerCounts[level]; layer++)
{ {
mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalformat, mImageArray[level][layer]->redefine(GL_TEXTURE_2D_ARRAY, internalformat,
gl::Extents(size.width, size.height, 1), false); gl::Extents(size.width, size.height, 1),
forceRelease);
} }
} }
...@@ -3292,11 +3297,10 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const ...@@ -3292,11 +3297,10 @@ void TextureD3D_2DArray::redefineImage(GLint level, GLenum internalformat, const
const GLenum storageFormat = getBaseLevelInternalFormat(); const GLenum storageFormat = getBaseLevelInternalFormat();
const int storageLevels = mTexStorage->getLevelCount(); const int storageLevels = mTexStorage->getLevelCount();
if ((level >= storageLevels && storageLevels != 0) || if (forceRelease || (level >= storageLevels && storageLevels != 0) ||
size.width != storageWidth || size.width != storageWidth || size.height != storageHeight ||
size.height != storageHeight ||
size.depth != storageDepth || size.depth != storageDepth ||
internalformat != storageFormat) // Discard mismatched storage internalformat != storageFormat) // Discard mismatched storage
{ {
markAllImagesDirty(); markAllImagesDirty();
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
......
...@@ -333,6 +333,37 @@ TEST_P(RobustResourceInitTest, ReadingUninitializedTexture) ...@@ -333,6 +333,37 @@ TEST_P(RobustResourceInitTest, ReadingUninitializedTexture)
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
} }
// Test that calling glTexImage2D multiple times with the same size and no data resets all texture
// data
TEST_P(RobustResourceInitTest, ReuploadingClearsTexture)
{
if (!setup())
{
return;
}
if (IsOpenGL() || IsD3D9())
{
std::cout << "Robust resource init is not yet fully implemented. (" << GetParam() << ")"
<< std::endl;
return;
}
// Put some data into the texture
std::array<GLColor, kWidth * kHeight> data;
data.fill(GLColor::white);
GLTexture tex;
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
data.data());
// Reset the texture
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
checkNonZeroPixels(&tex, 0, 0, 0, 0, GLColor::transparentBlack);
EXPECT_GL_NO_ERROR();
}
// Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0. // Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0.
TEST_P(RobustResourceInitTest, ReadingUninitialized3DTexture) TEST_P(RobustResourceInitTest, ReadingUninitialized3DTexture)
{ {
......
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