Added TEXTURE_SWIZZLE_* parameters to the texture sampler state and API queries.

Change-Id: I20aff392ec4cd9e49424afae94a862fdd8eef9b8
Reviewed-on: https://chromium-review.googlesource.com/177030
Reviewed-by: Shannon Woods <shannonwoods@chromium.org>
Commit-Queue: Shannon Woods <shannonwoods@chromium.org>
Tested-by: Shannon Woods <shannonwoods@chromium.org>
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 13dbd85..546f830 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -62,6 +62,10 @@
     mSamplerState.lodOffset = 0;
     mSamplerState.compareMode = GL_NONE;
     mSamplerState.compareFunc = GL_LEQUAL;
+    mSamplerState.swizzleRed = GL_RED;
+    mSamplerState.swizzleGreen = GL_GREEN;
+    mSamplerState.swizzleBlue = GL_BLUE;
+    mSamplerState.swizzleAlpha = GL_ALPHA;
     mUsage = GL_NONE;
 
     mDirtyImages = true;
@@ -130,6 +134,26 @@
     mSamplerState.compareFunc = func;
 }
 
+void Texture::setSwizzleRed(GLenum swizzle)
+{
+    mSamplerState.swizzleRed = swizzle;
+}
+
+void Texture::setSwizzleGreen(GLenum swizzle)
+{
+    mSamplerState.swizzleGreen = swizzle;
+}
+
+void Texture::setSwizzleBlue(GLenum swizzle)
+{
+    mSamplerState.swizzleBlue = swizzle;
+}
+
+void Texture::setSwizzleAlpha(GLenum swizzle)
+{
+    mSamplerState.swizzleAlpha = swizzle;
+}
+
 void Texture::setUsage(GLenum usage)
 {
     mUsage = usage;
@@ -165,6 +189,34 @@
     return mSamplerState.maxAnisotropy;
 }
 
+GLenum Texture::getSwizzleRed() const
+{
+    return mSamplerState.swizzleRed;
+}
+
+GLenum Texture::getSwizzleGreen() const
+{
+    return mSamplerState.swizzleGreen;
+}
+
+GLenum Texture::getSwizzleBlue() const
+{
+    return mSamplerState.swizzleBlue;
+}
+
+GLenum Texture::getSwizzleAlpha() const
+{
+    return mSamplerState.swizzleAlpha;
+}
+
+bool Texture::isSwizzled() const
+{
+    return mSamplerState.swizzleRed   != GL_RED   ||
+           mSamplerState.swizzleGreen != GL_GREEN ||
+           mSamplerState.swizzleBlue  != GL_BLUE  ||
+           mSamplerState.swizzleAlpha != GL_ALPHA;
+}
+
 int Texture::getLodOffset()
 {
     rx::TextureStorageInterface *texture = getNativeTexture();
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 07bef2e..9107156 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -77,6 +77,10 @@
     void setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAnisotropy);
     void setCompareMode(GLenum mode);
     void setCompareFunc(GLenum func);
+    void setSwizzleRed(GLenum swizzle);
+    void setSwizzleGreen(GLenum swizzle);
+    void setSwizzleBlue(GLenum swizzle);
+    void setSwizzleAlpha(GLenum swizzle);
     void setUsage(GLenum usage);
 
     GLenum getMinFilter() const;
@@ -85,6 +89,11 @@
     GLenum getWrapT() const;
     GLenum getWrapR() const;
     float getMaxAnisotropy() const;
+    GLenum getSwizzleRed() const;
+    GLenum getSwizzleGreen() const;
+    GLenum getSwizzleBlue() const;
+    GLenum getSwizzleAlpha() const;
+    bool isSwizzled() const;
     int getLodOffset();
     void getSamplerState(SamplerState *sampler);
     GLenum getUsage() const;
diff --git a/src/libGLESv2/angletypes.h b/src/libGLESv2/angletypes.h
index b5472cb..ea04d36 100644
--- a/src/libGLESv2/angletypes.h
+++ b/src/libGLESv2/angletypes.h
@@ -152,6 +152,11 @@
 
     GLenum compareMode;
     GLenum compareFunc;
+
+    GLenum swizzleRed;
+    GLenum swizzleGreen;
+    GLenum swizzleBlue;
+    GLenum swizzleAlpha;
 };
 
 struct ClearParameters
diff --git a/src/libGLESv2/libGLESv2.cpp b/src/libGLESv2/libGLESv2.cpp
index 17f1eb0..0364d3d 100644
--- a/src/libGLESv2/libGLESv2.cpp
+++ b/src/libGLESv2/libGLESv2.cpp
@@ -3751,6 +3751,34 @@
                 }
                 *params = (GLfloat)texture->getMaxAnisotropy();
                 break;
+              case GL_TEXTURE_SWIZZLE_R:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = (GLfloat)texture->getSwizzleRed();
+                break;
+              case GL_TEXTURE_SWIZZLE_G:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = (GLfloat)texture->getSwizzleGreen();
+                break;
+              case GL_TEXTURE_SWIZZLE_B:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = (GLfloat)texture->getSwizzleBlue();
+                break;
+              case GL_TEXTURE_SWIZZLE_A:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = (GLfloat)texture->getSwizzleAlpha();
+                break;
               default:
                 return gl::error(GL_INVALID_ENUM);
             }
@@ -3821,6 +3849,34 @@
                 }
                 *params = (GLint)texture->getMaxAnisotropy();
                 break;
+              case GL_TEXTURE_SWIZZLE_R:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = texture->getSwizzleRed();
+                break;
+              case GL_TEXTURE_SWIZZLE_G:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = texture->getSwizzleGreen();
+                break;
+              case GL_TEXTURE_SWIZZLE_B:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = texture->getSwizzleBlue();
+                break;
+              case GL_TEXTURE_SWIZZLE_A:
+                if (context->getClientVersion() < 3)
+                {
+                    return gl::error(GL_INVALID_ENUM);
+                }
+                *params = texture->getSwizzleAlpha();
+                break;
 
               default:
                 return gl::error(GL_INVALID_ENUM);
@@ -5181,11 +5237,11 @@
               case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->setMaxAnisotropy(static_cast<GLfloat>(param), context->getTextureMaxAnisotropy()); break;
               case GL_TEXTURE_COMPARE_MODE:         texture->setCompareMode(gl::uiround<GLenum>(param)); break;
               case GL_TEXTURE_COMPARE_FUNC:         texture->setCompareFunc(gl::uiround<GLenum>(param)); break;
+              case GL_TEXTURE_SWIZZLE_R:            texture->setSwizzleRed(gl::uiround<GLenum>(param));   break;
+              case GL_TEXTURE_SWIZZLE_G:            texture->setSwizzleGreen(gl::uiround<GLenum>(param)); break;
+              case GL_TEXTURE_SWIZZLE_B:            texture->setSwizzleBlue(gl::uiround<GLenum>(param));  break;
+              case GL_TEXTURE_SWIZZLE_A:            texture->setSwizzleAlpha(gl::uiround<GLenum>(param)); break;
 
-              case GL_TEXTURE_SWIZZLE_R:
-              case GL_TEXTURE_SWIZZLE_G:
-              case GL_TEXTURE_SWIZZLE_B:
-              case GL_TEXTURE_SWIZZLE_A:
               case GL_TEXTURE_BASE_LEVEL:
               case GL_TEXTURE_MAX_LEVEL:
               case GL_TEXTURE_MIN_LOD:
@@ -5241,11 +5297,11 @@
               case GL_TEXTURE_MAX_ANISOTROPY_EXT:   texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()); break;
               case GL_TEXTURE_COMPARE_MODE:         texture->setCompareMode((GLenum)param); break;
               case GL_TEXTURE_COMPARE_FUNC:         texture->setCompareFunc((GLenum)param); break;
+              case GL_TEXTURE_SWIZZLE_R:            texture->setSwizzleRed((GLenum)param);   break;
+              case GL_TEXTURE_SWIZZLE_G:            texture->setSwizzleGreen((GLenum)param); break;
+              case GL_TEXTURE_SWIZZLE_B:            texture->setSwizzleBlue((GLenum)param);  break;
+              case GL_TEXTURE_SWIZZLE_A:            texture->setSwizzleAlpha((GLenum)param); break;
 
-              case GL_TEXTURE_SWIZZLE_R:
-              case GL_TEXTURE_SWIZZLE_G:
-              case GL_TEXTURE_SWIZZLE_B:
-              case GL_TEXTURE_SWIZZLE_A:
               case GL_TEXTURE_BASE_LEVEL:
               case GL_TEXTURE_MAX_LEVEL:
               case GL_TEXTURE_MIN_LOD:
diff --git a/src/libGLESv2/validationES.cpp b/src/libGLESv2/validationES.cpp
index b3f8d90..fd3d4de 100644
--- a/src/libGLESv2/validationES.cpp
+++ b/src/libGLESv2/validationES.cpp
@@ -575,6 +575,20 @@
       case GL_TEXTURE_SWIZZLE_G:
       case GL_TEXTURE_SWIZZLE_B:
       case GL_TEXTURE_SWIZZLE_A:
+        switch (param)
+        {
+          case GL_RED:
+          case GL_GREEN:
+          case GL_BLUE:
+          case GL_ALPHA:
+          case GL_ZERO:
+          case GL_ONE:
+            return true;
+          default:
+            return gl::error(GL_INVALID_ENUM, false);
+        }
+        break;
+
       case GL_TEXTURE_BASE_LEVEL:
       case GL_TEXTURE_MAX_LEVEL:
         UNIMPLEMENTED();