OSDN Git Service

Use base level for mipmap generation and completeness.
authorNicolas Capens <capn@google.com>
Mon, 18 Dec 2017 20:58:46 +0000 (15:58 -0500)
committerNicolas Capens <nicolascapens@google.com>
Tue, 19 Dec 2017 20:28:14 +0000 (20:28 +0000)
Change-Id: Ibc557e4843d8106c07ae2f92c9628e10f228b1ae
Reviewed-on: https://swiftshader-review.googlesource.com/15208
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
src/OpenGL/libGLESv2/Texture.cpp
src/OpenGL/libGLESv2/libGLESv2.cpp

index 9ae1b11..4776d66 100644 (file)
@@ -786,16 +786,16 @@ void Texture2D::setSharedImage(egl::Image *sharedImage)
        image[0] = sharedImage;
 }
 
-// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+// Tests for 2D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
 bool Texture2D::isSamplerComplete() const
 {
-       if(!image[0])
+       if(!image[mBaseLevel])
        {
                return false;
        }
 
-       GLsizei width = image[0]->getWidth();
-       GLsizei height = image[0]->getHeight();
+       GLsizei width = image[mBaseLevel]->getWidth();
+       GLsizei height = image[mBaseLevel]->getHeight();
 
        if(width <= 0 || height <= 0)
        {
@@ -813,13 +813,19 @@ bool Texture2D::isSamplerComplete() const
        return true;
 }
 
-// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// Tests for 2D texture (mipmap) completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
 bool Texture2D::isMipmapComplete() const
 {
+       if(mBaseLevel > mMaxLevel)
+       {
+               return false;
+       }
+
        GLsizei width = image[mBaseLevel]->getWidth();
        GLsizei height = image[mBaseLevel]->getHeight();
-
-       int q = std::min(log2(std::max(width, height)), mMaxLevel);
+       int maxsize = std::max(width, height);
+       int p = log2(maxsize) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
        for(int level = mBaseLevel + 1; level <= q; level++)
        {
@@ -828,12 +834,12 @@ bool Texture2D::isMipmapComplete() const
                        return false;
                }
 
-               if(image[level]->getFormat() != image[0]->getFormat())
+               if(image[level]->getFormat() != image[mBaseLevel]->getFormat())
                {
                        return false;
                }
 
-               if(image[level]->getType() != image[0]->getType())
+               if(image[level]->getType() != image[mBaseLevel]->getType())
                {
                        return false;
                }
@@ -864,21 +870,20 @@ bool Texture2D::isDepth(GLenum target, GLint level) const
 
 void Texture2D::generateMipmaps()
 {
-       if(!image[0])
-       {
-               return;   // FIXME: error?
-       }
+       ASSERT(image[mBaseLevel]);
 
-       unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+       int maxsize = std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight());
+       int p = log2(maxsize) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
-       for(unsigned int i = 1; i <= q; i++)
+       for(int i = mBaseLevel + 1; i <= q; i++)
        {
                if(image[i])
                {
                        image[i]->release();
                }
 
-               image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType());
+               image[i] = egl::Image::create(this, std::max(image[mBaseLevel]->getWidth() >> i, 1), std::max(image[mBaseLevel]->getHeight() >> i, 1), image[mBaseLevel]->getFormat(), image[mBaseLevel]->getType());
 
                if(!image[i])
                {
@@ -1115,18 +1120,18 @@ void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffse
        Texture::subImageCompressed(xoffset, yoffset, 0, width, height, 1, format, imageSize, pixels, image[CubeFaceIndex(target)][level]);
 }
 
-// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
+// Tests for cube map sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 161.
 bool TextureCubeMap::isSamplerComplete() const
 {
        for(int face = 0; face < 6; face++)
        {
-               if(!image[face][0])
+               if(!image[face][mBaseLevel])
                {
                        return false;
                }
        }
 
-       int size = image[0][0]->getWidth();
+       int size = image[0][mBaseLevel]->getWidth();
 
        if(size <= 0)
        {
@@ -1151,7 +1156,7 @@ bool TextureCubeMap::isSamplerComplete() const
        return true;
 }
 
-// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// Tests for cube texture completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
 bool TextureCubeMap::isCubeComplete() const
 {
        if(image[0][mBaseLevel]->getWidth() <= 0 || image[0][mBaseLevel]->getHeight() != image[0][mBaseLevel]->getWidth())
@@ -1175,13 +1180,19 @@ bool TextureCubeMap::isCubeComplete() const
 
 bool TextureCubeMap::isMipmapCubeComplete() const
 {
+       if(mBaseLevel > mMaxLevel)
+       {
+               return false;
+       }
+
        if(!isCubeComplete())
        {
                return false;
        }
 
        GLsizei size = image[0][mBaseLevel]->getWidth();
-       int q = std::min(log2(size), mMaxLevel);
+       int p = log2(size) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
        for(int face = 0; face < 6; face++)
        {
@@ -1410,16 +1421,16 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
 
 void TextureCubeMap::generateMipmaps()
 {
-       if(!isCubeComplete())
-       {
-               return error(GL_INVALID_OPERATION);
-       }
+       ASSERT(isCubeComplete());
 
-       unsigned int q = log2(image[0][0]->getWidth());
+       int p = log2(image[0][mBaseLevel]->getWidth()) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
-       for(unsigned int f = 0; f < 6; f++)
+       for(int f = 0; f < 6; f++)
        {
-               for(unsigned int i = 1; i <= q; i++)
+               ASSERT(image[f][mBaseLevel]);
+
+               for(int i = mBaseLevel + 1; i <= q; i++)
                {
                        if(image[f][i])
                        {
@@ -1427,7 +1438,7 @@ void TextureCubeMap::generateMipmaps()
                        }
 
                        int border = (egl::getClientVersion() >= 3) ? 1 : 0;
-                       image[f][i] = egl::Image::create(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), 1, border, image[0][0]->getFormat(), image[0][0]->getType());
+                       image[f][i] = egl::Image::create(this, std::max(image[f][mBaseLevel]->getWidth() >> i, 1), std::max(image[f][mBaseLevel]->getHeight() >> i, 1), 1, border, image[f][mBaseLevel]->getFormat(), image[f][mBaseLevel]->getType());
 
                        if(!image[f][i])
                        {
@@ -1760,17 +1771,17 @@ void Texture3D::setSharedImage(egl::Image *sharedImage)
        image[0] = sharedImage;
 }
 
-// Tests for 3D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
+// Tests for 3D texture sampling completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
 bool Texture3D::isSamplerComplete() const
 {
-       if(!image[0])
+       if(!image[mBaseLevel])
        {
                return false;
        }
 
-       GLsizei width = image[0]->getWidth();
-       GLsizei height = image[0]->getHeight();
-       GLsizei depth = image[0]->getDepth();
+       GLsizei width = image[mBaseLevel]->getWidth();
+       GLsizei height = image[mBaseLevel]->getHeight();
+       GLsizei depth = image[mBaseLevel]->getDepth();
 
        if(width <= 0 || height <= 0 || depth <= 0)
        {
@@ -1788,16 +1799,22 @@ bool Texture3D::isSamplerComplete() const
        return true;
 }
 
-// Tests for 3D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
+// Tests for 3D texture (mipmap) completeness. [OpenGL ES 3.0.5] section 3.8.13 page 160.
 bool Texture3D::isMipmapComplete() const
 {
+       if(mBaseLevel > mMaxLevel)
+       {
+               return false;
+       }
+
        GLsizei width = image[mBaseLevel]->getWidth();
        GLsizei height = image[mBaseLevel]->getHeight();
        GLsizei depth = image[mBaseLevel]->getDepth();
        bool isTexture2DArray = getTarget() == GL_TEXTURE_2D_ARRAY;
 
-       int q = isTexture2DArray ? std::min(log2(std::max(width, height)), mMaxLevel) :
-               std::min(log2(std::max(std::max(width, height), depth)), mMaxLevel);
+       int maxsize = isTexture2DArray ? std::max(width, height) : std::max(std::max(width, height), depth);
+       int p = log2(maxsize) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
        for(int level = mBaseLevel + 1; level <= q; level++)
        {
@@ -1806,12 +1823,12 @@ bool Texture3D::isMipmapComplete() const
                        return false;
                }
 
-               if(image[level]->getFormat() != image[0]->getFormat())
+               if(image[level]->getFormat() != image[mBaseLevel]->getFormat())
                {
                        return false;
                }
 
-               if(image[level]->getType() != image[0]->getType())
+               if(image[level]->getType() != image[mBaseLevel]->getType())
                {
                        return false;
                }
@@ -1848,21 +1865,20 @@ bool Texture3D::isDepth(GLenum target, GLint level) const
 
 void Texture3D::generateMipmaps()
 {
-       if(!image[0])
-       {
-               return;   // FIXME: error?
-       }
+       ASSERT(image[mBaseLevel]);
 
-       unsigned int q = log2(std::max(std::max(image[0]->getWidth(), image[0]->getHeight()), image[0]->getDepth()));
+       int maxsize = std::max(std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight()), image[mBaseLevel]->getDepth());
+       int p = log2(maxsize) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
-       for(unsigned int i = 1; i <= q; i++)
+       for(int i = mBaseLevel + 1; i <= q; i++)
        {
                if(image[i])
                {
                        image[i]->release();
                }
 
-               image[i] = egl::Image::create(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), std::max(image[0]->getDepth() >> i, 1), 0, image[0]->getFormat(), image[0]->getType());
+               image[i] = egl::Image::create(this, std::max(image[mBaseLevel]->getWidth() >> i, 1), std::max(image[mBaseLevel]->getHeight() >> i, 1), std::max(image[mBaseLevel]->getDepth() >> i, 1), 0, image[mBaseLevel]->getFormat(), image[mBaseLevel]->getType());
 
                if(!image[i])
                {
@@ -1943,24 +1959,23 @@ GLenum Texture2DArray::getTarget() const
 
 void Texture2DArray::generateMipmaps()
 {
-       int depth = image[0] ? image[0]->getDepth() : 0;
-       if(!depth)
-       {
-               return;   // FIXME: error?
-       }
+       ASSERT(image[mBaseLevel]);
 
-       unsigned int q = log2(std::max(image[0]->getWidth(), image[0]->getHeight()));
+       int depth = image[mBaseLevel]->getDepth();
+       int maxsize = std::max(image[mBaseLevel]->getWidth(), image[mBaseLevel]->getHeight());
+       int p = log2(maxsize) + mBaseLevel;
+       int q = std::min(p, mMaxLevel);
 
-       for(unsigned int i = 1; i <= q; i++)
+       for(int i = mBaseLevel + 1; i <= q; i++)
        {
                if(image[i])
                {
                        image[i]->release();
                }
 
-               GLsizei w = std::max(image[0]->getWidth() >> i, 1);
-               GLsizei h = std::max(image[0]->getHeight() >> i, 1);
-               image[i] = egl::Image::create(this, w, h, depth, 0, image[0]->getFormat(), image[0]->getType());
+               GLsizei w = std::max(image[mBaseLevel]->getWidth() >> i, 1);
+               GLsizei h = std::max(image[mBaseLevel]->getHeight() >> i, 1);
+               image[i] = egl::Image::create(this, w, h, depth, 0, image[mBaseLevel]->getFormat(), image[mBaseLevel]->getType());
 
                if(!image[i])
                {
index f9cbde1..9f96d47 100644 (file)
@@ -2288,7 +2288,7 @@ void GenerateMipmap(GLenum target)
                        return error(GL_INVALID_ENUM);
                }
 
-               if(!IsMipmappable(texture->getFormat(target, 0), clientVersion))
+               if(!IsMipmappable(texture->getFormat(target, texture->getBaseLevel()), clientVersion))
                {
                        return error(GL_INVALID_OPERATION);
                }