Fix off-by-one error with the number of storage mip levels.
This caused there to be too few mip levels in the TextureStorage and it
would be discarded if there was a modification to a lower mip.
Also modified Texture::mipLevels to return the number of mip levels rather
than the index of the smallest mip to avoid confusion.
Fixes WebGL D3D9 conformance failures in:
mipmap-fbo
BUG=angleproject:550
Change-Id: Idf3f543487232edceb520337331b39dab2bd26ba
Reviewed-on: https://chromium-review.googlesource.com/192341
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index a1a447c..f143994 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -400,7 +400,7 @@
if ((isPow2(width) && isPow2(height) && isPow2(depth)) || mRenderer->getNonPower2TextureSupport())
{
// Maximum number of levels
- return static_cast<GLint>(log2(std::max(std::max(width, height), depth)));
+ return log2(std::max(std::max(width, height), depth)) + 1;
}
else
{
@@ -411,7 +411,7 @@
int Texture::mipLevels() const
{
- return static_cast<int>(log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())));
+ return log2(std::max(std::max(getBaseLevelWidth(), getBaseLevelHeight()), getBaseLevelDepth())) + 1;
}
Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D)
@@ -800,9 +800,9 @@
// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool Texture2D::isMipmapComplete() const
{
- int q = mipLevels();
+ int levelCount = mipLevels();
- for (int level = 0; level <= q; level++)
+ for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
@@ -953,8 +953,8 @@
void Texture2D::generateMipmaps()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
- int q = mipLevels();
- for (int level = 1; level <= q; level++)
+ int levelCount = mipLevels();
+ for (int level = 1; level < levelCount; level++)
{
redefineImage(level, getBaseLevelInternalFormat(),
std::max(getBaseLevelWidth() >> level, 1),
@@ -963,7 +963,7 @@
if (mTexStorage && mTexStorage->isRenderTarget())
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mTexStorage->generateMipmap(level);
@@ -972,7 +972,7 @@
}
else
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
}
@@ -1255,11 +1255,11 @@
return false;
}
- int q = mipLevels();
+ int levelCount = mipLevels();
for (int face = 0; face < 6; face++)
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
if (!isFaceLevelComplete(face, level))
{
@@ -1585,10 +1585,10 @@
void TextureCubeMap::generateMipmaps()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
- int q = mipLevels();
+ int levelCount = mipLevels();
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
int faceLevelSize = (std::max(mImageArray[faceIndex][0]->getWidth() >> level, 1));
redefineImage(faceIndex, level, mImageArray[faceIndex][0]->getInternalFormat(), faceLevelSize, faceLevelSize);
@@ -1599,7 +1599,7 @@
{
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mTexStorage->generateMipmap(faceIndex, level);
@@ -1611,7 +1611,7 @@
{
for (int faceIndex = 0; faceIndex < 6; faceIndex++)
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mRenderer->generateMipmap(mImageArray[faceIndex][level], mImageArray[faceIndex][level - 1]);
}
@@ -1853,8 +1853,8 @@
void Texture3D::generateMipmaps()
{
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
- int q = mipLevels();
- for (int level = 1; level <= q; level++)
+ int levelCount = mipLevels();
+ for (int level = 1; level < levelCount; level++)
{
redefineImage(level, getBaseLevelInternalFormat(),
std::max(getBaseLevelWidth() >> level, 1),
@@ -1864,7 +1864,7 @@
if (mTexStorage && mTexStorage->isRenderTarget())
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mTexStorage->generateMipmap(level);
@@ -1873,7 +1873,7 @@
}
else
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mRenderer->generateMipmap(mImageArray[level], mImageArray[level - 1]);
}
@@ -1959,9 +1959,9 @@
bool Texture3D::isMipmapComplete() const
{
- int q = mipLevels();
+ int levelCount = mipLevels();
- for (int level = 0; level <= q; level++)
+ for (int level = 0; level < levelCount; level++)
{
if (!isLevelComplete(level))
{
@@ -2407,15 +2407,15 @@
GLenum baseFormat = getBaseLevelInternalFormat();
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
- int q = mipLevels();
- for (int level = 1; level <= q; level++)
+ int levelCount = mipLevels();
+ for (int level = 1; level < levelCount; level++)
{
redefineImage(level, baseFormat, std::max(baseWidth >> level, 1), std::max(baseHeight >> level, 1), baseDepth);
}
if (mTexStorage && mTexStorage->isRenderTarget())
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
mTexStorage->generateMipmap(level);
@@ -2427,7 +2427,7 @@
}
else
{
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
@@ -2515,9 +2515,9 @@
bool Texture2DArray::isMipmapComplete() const
{
- int q = mipLevels();
+ int levelCount = mipLevels();
- for (int level = 1; level <= q; level++)
+ for (int level = 1; level < levelCount; level++)
{
if (!isLevelComplete(level))
{