Support GL_OES_texture_border_clamp

Added support for GL_TEXTURE_BORDER_COLOR and GL_CLAMP_TO_BORDER in
OpenGL/OpenGLES, Direct3D9 and Direct3D11 backends.
For integer textures in OpenGLES3 contexts these additional entry points
are available now:

void glTexParameterIivOES(enum target, enum pname, const int *params);
void glTexParameterIuivOES(enum target, enum pname, const uint *params);

void glGetTexParameterIivOES(enum target, enum pname, int *params);
void glGetTexParameterIuivOES(enum target, enum pname, uint *params);

void glSamplerParameterIivOES(uint sampler, enum pname, const int *params);
void glSamplerParameterIuivOES(uint sampler, enum pname, const uint *params);

void glGetSamplerParameterIivOES(uint sampler, enum pname, int *params);
void glGetSamplerParameterIuivOES(uint sampler, enum pname, uint *params);

BUG=angleproject:2890
TEST=angle_end2end_tests.TextureBorderClamp*

Change-Id: Iee3eeb399d8d7851b3b30694ad8f21a2111f5828
Reviewed-on: https://chromium-review.googlesource.com/c/1257824
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 37c424d..2322240 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -229,6 +229,14 @@
         case GL_CLAMP_TO_EDGE:
             break;
 
+        case GL_CLAMP_TO_BORDER:
+            if (!context->getExtensions().textureBorderClamp)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
+                return false;
+            }
+            break;
+
         case GL_REPEAT:
         case GL_MIRRORED_REPEAT:
             if (restrictedWrapModes)
@@ -462,6 +470,12 @@
             return false;
     }
 }
+
+unsigned int GetSamplerParameterCount(GLenum pname)
+{
+    return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
+}
+
 }  // anonymous namespace
 
 void SetRobustLengthParam(GLsizei *length, GLsizei value)
@@ -4703,7 +4717,7 @@
         return false;
     }
 
-    return ValidateTexParameterBase(context, target, pname, bufSize, params);
+    return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
 }
 
 bool ValidateTexParameterivRobustANGLE(Context *context,
@@ -4717,7 +4731,7 @@
         return false;
     }
 
-    return ValidateTexParameterBase(context, target, pname, bufSize, params);
+    return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
 }
 
 bool ValidateTexParameterIivRobustANGLE(Context *context,
@@ -4829,7 +4843,7 @@
         return false;
     }
 
-    return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
+    return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
 }
 
 bool ValidateSamplerParameterivRobustANGLE(Context *context,
@@ -4843,7 +4857,7 @@
         return false;
     }
 
-    return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
+    return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
 }
 
 bool ValidateSamplerParameterIivRobustANGLE(Context *context,
@@ -5531,6 +5545,14 @@
             }
             break;
 
+        case GL_TEXTURE_BORDER_COLOR:
+            if (!context->getExtensions().textureBorderClamp)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
+                return false;
+            }
+            break;
+
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
@@ -5880,6 +5902,7 @@
                               TextureType target,
                               GLenum pname,
                               GLsizei bufSize,
+                              bool vectorParams,
                               const ParamType *params)
 {
     if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
@@ -5960,6 +5983,7 @@
             case GL_TEXTURE_MAX_LOD:
             case GL_TEXTURE_COMPARE_MODE:
             case GL_TEXTURE_COMPARE_FUNC:
+            case GL_TEXTURE_BORDER_COLOR:
                 context->handleError(InvalidEnum()
                                      << "Invalid parameter for 2D multisampled textures.");
                 return false;
@@ -6130,13 +6154,39 @@
             break;
 
         case GL_GENERATE_MIPMAP:
-        case GL_TEXTURE_CROP_RECT_OES:
             if (context->getClientMajorVersion() > 1)
             {
                 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
                 return false;
             }
             break;
+
+        case GL_TEXTURE_CROP_RECT_OES:
+            if (context->getClientMajorVersion() > 1)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
+                return false;
+            }
+            if (!vectorParams)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
+                return false;
+            }
+            break;
+
+        case GL_TEXTURE_BORDER_COLOR:
+            if (!context->getExtensions().textureBorderClamp)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
+                return false;
+            }
+            if (!vectorParams)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), InsufficientBufferSize);
+                return false;
+            }
+            break;
+
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
@@ -6145,8 +6195,24 @@
     return true;
 }
 
-template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLfloat *);
-template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLint *);
+template bool ValidateTexParameterBase(Context *,
+                                       TextureType,
+                                       GLenum,
+                                       GLsizei,
+                                       bool,
+                                       const GLfloat *);
+template bool ValidateTexParameterBase(Context *,
+                                       TextureType,
+                                       GLenum,
+                                       GLsizei,
+                                       bool,
+                                       const GLint *);
+template bool ValidateTexParameterBase(Context *,
+                                       TextureType,
+                                       GLenum,
+                                       GLsizei,
+                                       bool,
+                                       const GLuint *);
 
 bool ValidateVertexAttribIndex(Context *context, GLuint index)
 {
@@ -6227,6 +6293,7 @@
                                   GLuint sampler,
                                   GLenum pname,
                                   GLsizei bufSize,
+                                  bool vectorParams,
                                   ParamType *params)
 {
     if (context->getClientMajorVersion() < 3)
@@ -6241,7 +6308,7 @@
         return false;
     }
 
-    const GLsizei minBufSize = 1;
+    const GLsizei minBufSize = GetSamplerParameterCount(pname);
     if (bufSize >= 0 && bufSize < minBufSize)
     {
         ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
@@ -6309,6 +6376,19 @@
         }
         break;
 
+        case GL_TEXTURE_BORDER_COLOR:
+            if (!context->getExtensions().textureBorderClamp)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
+                return false;
+            }
+            if (!vectorParams)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), InsufficientBufferSize);
+                return false;
+            }
+            break;
+
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
@@ -6317,8 +6397,14 @@
     return true;
 }
 
-template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLfloat *);
-template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLint *);
+template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
+template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
+template bool ValidateSamplerParameterBase(Context *,
+                                           GLuint,
+                                           GLenum,
+                                           GLsizei,
+                                           bool,
+                                           const GLuint *);
 
 bool ValidateGetSamplerParameterBase(Context *context,
                                      GLuint sampler,
@@ -6370,6 +6456,14 @@
             }
             break;
 
+        case GL_TEXTURE_BORDER_COLOR:
+            if (!context->getExtensions().textureBorderClamp)
+            {
+                ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
+                return false;
+            }
+            break;
+
         default:
             ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
             return false;
@@ -6377,7 +6471,7 @@
 
     if (length)
     {
-        *length = 1;
+        *length = GetSamplerParameterCount(pname);
     }
     return true;
 }