Commit e76bdda2 by Jamie Madill

Restrict use of TexStorage more in CopyImage.

We were being too permissive in some copyImage methods when checking if we can create a render target or not. This would lead us to trying to use an inconsistent TexStorage in some cases. Note that we do need to create inconsistent TexStorage in cases where we are doing a FBO copy *from* a mipmap-incomplete texture attachment. BUG=angle:780 Change-Id: I5a849b5d8c53713e38cb5f5052a8bb88b3f56260 Reviewed-on: https://chromium-review.googlesource.com/224480Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShannon Woods <shannonwoods@chromium.org>
parent 4a20480e
......@@ -431,6 +431,13 @@ gl::Error TextureD3D::ensureRenderTarget()
return gl::Error(GL_NO_ERROR);
}
bool TextureD3D::canCreateRenderTargetForImage(const gl::ImageIndex &index) const
{
rx::Image *image = getImage(index);
bool levelsComplete = (isImageComplete(index) && isImageComplete(getImageIndex(0, 0)));
return (image->isRenderableFormat() && levelsComplete);
}
TextureD3D_2D::TextureD3D_2D(Renderer *renderer)
: TextureD3D(renderer)
{
......@@ -640,8 +647,9 @@ gl::Error TextureD3D_2D::copyImage(GLenum target, GLint level, GLenum format, GL
redefineImage(level, sizedInternalFormat, width, height);
gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
if (!mImageArray[level]->isRenderableFormat())
if (!canCreateRenderTargetForImage(index))
{
gl::Error error = mImageArray[level]->copy(0, 0, 0, sourceRect, source);
if (error.isError())
......@@ -681,11 +689,11 @@ gl::Error TextureD3D_2D::copySubImage(GLenum target, GLint level, GLint xoffset,
// can only make our texture storage to a render target if level 0 is defined (with a width & height) and
// the current level we're copying to is defined (with appropriate format, width & height)
bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make2D(level);
if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
if (!canCreateRenderTargetForImage(index))
{
gl::Error error = mImageArray[level]->copy(xoffset, yoffset, 0, sourceRect, source);
if (error.isError())
......@@ -872,6 +880,11 @@ bool TextureD3D_2D::isLevelComplete(int level) const
return true;
}
bool TextureD3D_2D::isImageComplete(const gl::ImageIndex &index) const
{
return isLevelComplete(index.mipIndex);
}
// Constructs a native texture resource from the texture images
gl::Error TextureD3D_2D::initializeStorage(bool renderTarget)
{
......@@ -1177,8 +1190,9 @@ gl::Error TextureD3D_Cube::copyImage(GLenum target, GLint level, GLenum format,
redefineImage(faceIndex, level, sizedInternalFormat, width, height);
gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
if (!mImageArray[faceIndex][level]->isRenderableFormat())
if (!canCreateRenderTargetForImage(index))
{
gl::Error error = mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
if (error.isError())
......@@ -1218,14 +1232,10 @@ gl::Error TextureD3D_Cube::copySubImage(GLenum target, GLint level, GLint xoffse
{
int faceIndex = gl::TextureCubeMap::targetToLayerIndex(target);
// We can only make our texture storage to a render target if the level we're copying *to* is complete
// and the base level is cube-complete. The base level must be cube complete (common case) because we cannot
// rely on the "getBaseLevel*" methods reliably otherwise.
bool canCreateRenderTarget = isFaceLevelComplete(faceIndex, level) && isCubeComplete();
gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::MakeCube(target, level);
if (!mImageArray[faceIndex][level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
if (!canCreateRenderTargetForImage(index))
{
gl::Error error =mImageArray[faceIndex][level]->copy(0, 0, 0, sourceRect, source);
if (error.isError())
......@@ -1526,6 +1536,11 @@ bool TextureD3D_Cube::isFaceLevelComplete(int faceIndex, int level) const
return true;
}
bool TextureD3D_Cube::isImageComplete(const gl::ImageIndex &index) const
{
return isFaceLevelComplete(index.layerIndex, index.mipIndex);
}
gl::Error TextureD3D_Cube::updateStorageFaceLevel(int faceIndex, int level)
{
ASSERT(level >= 0 && faceIndex < 6 && level < (int)ArraySize(mImageArray[faceIndex]) && mImageArray[faceIndex][level] != NULL);
......@@ -1826,13 +1841,10 @@ gl::Error TextureD3D_3D::copySubImage(GLenum target, GLint level, GLint xoffset,
{
ASSERT(target == GL_TEXTURE_3D);
// can only make our texture storage to a render target if level 0 is defined (with a width & height) and
// the current level we're copying to is defined (with appropriate format, width & height)
bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make3D(level);
if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
if (canCreateRenderTargetForImage(index))
{
gl::Error error = mImageArray[level]->copy(xoffset, yoffset, zoffset, sourceRect, source);
if (error.isError())
......@@ -2106,6 +2118,11 @@ bool TextureD3D_3D::isLevelComplete(int level) const
return true;
}
bool TextureD3D_3D::isImageComplete(const gl::ImageIndex &index) const
{
return isLevelComplete(index.mipIndex);
}
gl::Error TextureD3D_3D::updateStorageLevel(int level)
{
ASSERT(level >= 0 && level < (int)ArraySize(mImageArray) && mImageArray[level] != NULL);
......@@ -2368,13 +2385,10 @@ gl::Error TextureD3D_2DArray::copySubImage(GLenum target, GLint level, GLint xof
{
ASSERT(target == GL_TEXTURE_2D_ARRAY);
// can only make our texture storage to a render target if level 0 is defined (with a width & height) and
// the current level we're copying to is defined (with appropriate format, width & height)
bool canCreateRenderTarget = isLevelComplete(level) && isLevelComplete(0);
gl::Rectangle sourceRect(x, y, width, height);
gl::ImageIndex index = gl::ImageIndex::Make2DArray(level, zoffset);
if (!mImageArray[level][0]->isRenderableFormat() || (!mTexStorage && !canCreateRenderTarget))
if (canCreateRenderTargetForImage(index))
{
gl::Error error = mImageArray[level][zoffset]->copy(xoffset, yoffset, 0, sourceRect, source);
if (error.isError())
......@@ -2645,6 +2659,11 @@ bool TextureD3D_2DArray::isLevelComplete(int level) const
return true;
}
bool TextureD3D_2DArray::isImageComplete(const gl::ImageIndex &index) const
{
return isLevelComplete(index.mipIndex);
}
gl::Error TextureD3D_2DArray::updateStorageLevel(int level)
{
ASSERT(level >= 0 && level < (int)ArraySize(mLayerCounts));
......
......@@ -77,7 +77,9 @@ class TextureD3D : public TextureImpl
int mipLevels() const;
virtual void initMipmapsImages() = 0;
bool isBaseImageZeroSize() const;
virtual bool isImageComplete(const gl::ImageIndex &index) const = 0;
bool canCreateRenderTargetForImage(const gl::ImageIndex &index) const;
virtual gl::Error ensureRenderTarget();
virtual gl::Error createCompleteStorage(bool renderTarget, TextureStorage **outTexStorage) const = 0;
......@@ -149,6 +151,7 @@ class TextureD3D_2D : public TextureD3D
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
virtual bool isImageComplete(const gl::ImageIndex &index) const;
gl::Error updateStorageLevel(int level);
......@@ -205,6 +208,7 @@ class TextureD3D_Cube : public TextureD3D
bool isValidFaceLevel(int faceIndex, int level) const;
bool isFaceLevelComplete(int faceIndex, int level) const;
bool isCubeComplete() const;
virtual bool isImageComplete(const gl::ImageIndex &index) const;
gl::Error updateStorageFaceLevel(int faceIndex, int level);
void redefineImage(int faceIndex, GLint level, GLenum internalformat, GLsizei width, GLsizei height);
......@@ -258,6 +262,7 @@ class TextureD3D_3D : public TextureD3D
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
virtual bool isImageComplete(const gl::ImageIndex &index) const;
gl::Error updateStorageLevel(int level);
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
......@@ -310,6 +315,7 @@ class TextureD3D_2DArray : public TextureD3D
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
virtual bool isImageComplete(const gl::ImageIndex &index) const;
gl::Error updateStorageLevel(int level);
void deleteImages();
......
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