xref: /aosp_15_r20/external/angle/src/libANGLE/validationES.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // validationES.h: Validation functions for generic OpenGL ES entry point parameters
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationES.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ErrorStrings.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Framebuffer.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/FramebufferAttachment.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Image.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/PixelLocalStorage.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Program.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Query.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Texture.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/TransformFeedback.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/angletypes.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/formatutils.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/queryconversions.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/queryutils.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationES2.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationES3.h"
28*8975f5c5SAndroid Build Coastguard Worker 
29*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
31*8975f5c5SAndroid Build Coastguard Worker 
32*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker namespace gl
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker using namespace err;
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker namespace
39*8975f5c5SAndroid Build Coastguard Worker {
CompressedTextureFormatRequiresExactSize(GLenum internalFormat)40*8975f5c5SAndroid Build Coastguard Worker bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     // List of compressed format that require that the texture size is smaller than or a multiple of
43*8975f5c5SAndroid Build Coastguard Worker     // the compressed block size.
44*8975f5c5SAndroid Build Coastguard Worker     switch (internalFormat)
45*8975f5c5SAndroid Build Coastguard Worker     {
46*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
47*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
48*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
49*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
50*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
51*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
52*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
53*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
54*8975f5c5SAndroid Build Coastguard Worker         case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
55*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
56*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
57*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
58*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
59*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
60*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
61*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RED_RGTC1_EXT:
62*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
63*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
64*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
65*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
66*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
67*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
68*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
69*8975f5c5SAndroid Build Coastguard Worker             return true;
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker         default:
72*8975f5c5SAndroid Build Coastguard Worker             return false;
73*8975f5c5SAndroid Build Coastguard Worker     }
74*8975f5c5SAndroid Build Coastguard Worker }
75*8975f5c5SAndroid Build Coastguard Worker 
DifferenceCanOverflow(GLint a,GLint b)76*8975f5c5SAndroid Build Coastguard Worker bool DifferenceCanOverflow(GLint a, GLint b)
77*8975f5c5SAndroid Build Coastguard Worker {
78*8975f5c5SAndroid Build Coastguard Worker     CheckedNumeric<GLint> checkedA(a);
79*8975f5c5SAndroid Build Coastguard Worker     checkedA -= b;
80*8975f5c5SAndroid Build Coastguard Worker     // Use negation to make sure that the difference can't overflow regardless of the order.
81*8975f5c5SAndroid Build Coastguard Worker     checkedA = -checkedA;
82*8975f5c5SAndroid Build Coastguard Worker     return !checkedA.IsValid();
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
ValidReadPixelsTypeEnum(const Context * context,GLenum type)85*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsTypeEnum(const Context *context, GLenum type)
86*8975f5c5SAndroid Build Coastguard Worker {
87*8975f5c5SAndroid Build Coastguard Worker     switch (type)
88*8975f5c5SAndroid Build Coastguard Worker     {
89*8975f5c5SAndroid Build Coastguard Worker         // Types referenced in Table 3.4 of the ES 2.0.25 spec
90*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_BYTE:
91*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT_4_4_4_4:
92*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT_5_5_5_1:
93*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT_5_6_5:
94*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_2_0;
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker         // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
97*8975f5c5SAndroid Build Coastguard Worker         case GL_BYTE:
98*8975f5c5SAndroid Build Coastguard Worker         case GL_INT:
99*8975f5c5SAndroid Build Coastguard Worker         case GL_SHORT:
100*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT:
101*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_10F_11F_11F_REV:
102*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_2_10_10_10_REV:
103*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_5_9_9_9_REV:
104*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT:
105*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
106*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
107*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0;
108*8975f5c5SAndroid Build Coastguard Worker 
109*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT:
110*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0 ||
111*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureFloatOES ||
112*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().colorBufferHalfFloatEXT;
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker         case GL_HALF_FLOAT:
115*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0 ||
116*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureHalfFloatOES;
117*8975f5c5SAndroid Build Coastguard Worker 
118*8975f5c5SAndroid Build Coastguard Worker         case GL_HALF_FLOAT_OES:
119*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().colorBufferHalfFloatEXT;
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker         default:
122*8975f5c5SAndroid Build Coastguard Worker             return false;
123*8975f5c5SAndroid Build Coastguard Worker     }
124*8975f5c5SAndroid Build Coastguard Worker }
125*8975f5c5SAndroid Build Coastguard Worker 
ValidReadPixelsFormatEnum(const Context * context,GLenum format)126*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsFormatEnum(const Context *context, GLenum format)
127*8975f5c5SAndroid Build Coastguard Worker {
128*8975f5c5SAndroid Build Coastguard Worker     switch (format)
129*8975f5c5SAndroid Build Coastguard Worker     {
130*8975f5c5SAndroid Build Coastguard Worker         // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
131*8975f5c5SAndroid Build Coastguard Worker         case GL_RGBA:
132*8975f5c5SAndroid Build Coastguard Worker         case GL_RGB:
133*8975f5c5SAndroid Build Coastguard Worker         case GL_ALPHA:
134*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_2_0;
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker         // Formats referenced in Table 3.2 of the ES 3.0.5 spec
137*8975f5c5SAndroid Build Coastguard Worker         case GL_RG:
138*8975f5c5SAndroid Build Coastguard Worker         case GL_RED:
139*8975f5c5SAndroid Build Coastguard Worker         case GL_RGBA_INTEGER:
140*8975f5c5SAndroid Build Coastguard Worker         case GL_RGB_INTEGER:
141*8975f5c5SAndroid Build Coastguard Worker         case GL_RG_INTEGER:
142*8975f5c5SAndroid Build Coastguard Worker         case GL_RED_INTEGER:
143*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0;
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker         case GL_SRGB_ALPHA_EXT:
146*8975f5c5SAndroid Build Coastguard Worker         case GL_SRGB_EXT:
147*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().sRGBEXT;
148*8975f5c5SAndroid Build Coastguard Worker 
149*8975f5c5SAndroid Build Coastguard Worker         case GL_BGRA_EXT:
150*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().readFormatBgraEXT;
151*8975f5c5SAndroid Build Coastguard Worker 
152*8975f5c5SAndroid Build Coastguard Worker         case GL_RGBX8_ANGLE:
153*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().rgbxInternalFormatANGLE;
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker         default:
156*8975f5c5SAndroid Build Coastguard Worker             return false;
157*8975f5c5SAndroid Build Coastguard Worker     }
158*8975f5c5SAndroid Build Coastguard Worker }
159*8975f5c5SAndroid Build Coastguard Worker 
ValidReadPixelsUnsignedNormalizedDepthType(const Context * context,const gl::InternalFormat * info,GLenum type)160*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsUnsignedNormalizedDepthType(const Context *context,
161*8975f5c5SAndroid Build Coastguard Worker                                                 const gl::InternalFormat *info,
162*8975f5c5SAndroid Build Coastguard Worker                                                 GLenum type)
163*8975f5c5SAndroid Build Coastguard Worker {
164*8975f5c5SAndroid Build Coastguard Worker     bool supportsReadDepthNV = context->getExtensions().readDepthNV && (info->depthBits > 0);
165*8975f5c5SAndroid Build Coastguard Worker     switch (type)
166*8975f5c5SAndroid Build Coastguard Worker     {
167*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_SHORT:
168*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT:
169*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT_24_8:
170*8975f5c5SAndroid Build Coastguard Worker             return supportsReadDepthNV;
171*8975f5c5SAndroid Build Coastguard Worker         default:
172*8975f5c5SAndroid Build Coastguard Worker             return false;
173*8975f5c5SAndroid Build Coastguard Worker     }
174*8975f5c5SAndroid Build Coastguard Worker }
175*8975f5c5SAndroid Build Coastguard Worker 
ValidReadPixelsFloatDepthType(const Context * context,const gl::InternalFormat * info,GLenum type)176*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsFloatDepthType(const Context *context,
177*8975f5c5SAndroid Build Coastguard Worker                                    const gl::InternalFormat *info,
178*8975f5c5SAndroid Build Coastguard Worker                                    GLenum type)
179*8975f5c5SAndroid Build Coastguard Worker {
180*8975f5c5SAndroid Build Coastguard Worker     return context->getExtensions().readDepthNV && (type == GL_FLOAT) &&
181*8975f5c5SAndroid Build Coastguard Worker            context->getExtensions().depthBufferFloat2NV;
182*8975f5c5SAndroid Build Coastguard Worker }
183*8975f5c5SAndroid Build Coastguard Worker 
ValidReadPixelsFormatType(const Context * context,const gl::InternalFormat * info,GLenum format,GLenum type)184*8975f5c5SAndroid Build Coastguard Worker bool ValidReadPixelsFormatType(const Context *context,
185*8975f5c5SAndroid Build Coastguard Worker                                const gl::InternalFormat *info,
186*8975f5c5SAndroid Build Coastguard Worker                                GLenum format,
187*8975f5c5SAndroid Build Coastguard Worker                                GLenum type)
188*8975f5c5SAndroid Build Coastguard Worker {
189*8975f5c5SAndroid Build Coastguard Worker     switch (info->componentType)
190*8975f5c5SAndroid Build Coastguard Worker     {
191*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_NORMALIZED:
192*8975f5c5SAndroid Build Coastguard Worker             // TODO(geofflang): Don't accept BGRA here.  Some chrome internals appear to try to use
193*8975f5c5SAndroid Build Coastguard Worker             // ReadPixels with BGRA even if the extension is not present
194*8975f5c5SAndroid Build Coastguard Worker             switch (format)
195*8975f5c5SAndroid Build Coastguard Worker             {
196*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA:
197*8975f5c5SAndroid Build Coastguard Worker                     return type == GL_UNSIGNED_BYTE ||
198*8975f5c5SAndroid Build Coastguard Worker                            (context->getExtensions().textureNorm16EXT &&
199*8975f5c5SAndroid Build Coastguard Worker                             type == GL_UNSIGNED_SHORT && info->type == GL_UNSIGNED_SHORT);
200*8975f5c5SAndroid Build Coastguard Worker                 case GL_BGRA_EXT:
201*8975f5c5SAndroid Build Coastguard Worker                     return context->getExtensions().readFormatBgraEXT && (type == GL_UNSIGNED_BYTE);
202*8975f5c5SAndroid Build Coastguard Worker                 case GL_STENCIL_INDEX_OES:
203*8975f5c5SAndroid Build Coastguard Worker                     return context->getExtensions().readStencilNV && (type == GL_UNSIGNED_BYTE);
204*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_COMPONENT:
205*8975f5c5SAndroid Build Coastguard Worker                     return ValidReadPixelsUnsignedNormalizedDepthType(context, info, type);
206*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_STENCIL_OES:
207*8975f5c5SAndroid Build Coastguard Worker                     return context->getExtensions().readDepthStencilNV &&
208*8975f5c5SAndroid Build Coastguard Worker                            (type == GL_UNSIGNED_INT_24_8_OES) && info->stencilBits > 0;
209*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBX8_ANGLE:
210*8975f5c5SAndroid Build Coastguard Worker                     return context->getExtensions().rgbxInternalFormatANGLE &&
211*8975f5c5SAndroid Build Coastguard Worker                            (type == GL_UNSIGNED_BYTE);
212*8975f5c5SAndroid Build Coastguard Worker                 default:
213*8975f5c5SAndroid Build Coastguard Worker                     return false;
214*8975f5c5SAndroid Build Coastguard Worker             }
215*8975f5c5SAndroid Build Coastguard Worker         case GL_SIGNED_NORMALIZED:
216*8975f5c5SAndroid Build Coastguard Worker             ASSERT(context->getExtensions().renderSnormEXT);
217*8975f5c5SAndroid Build Coastguard Worker             ASSERT(info->type == GL_BYTE ||
218*8975f5c5SAndroid Build Coastguard Worker                    (context->getExtensions().textureNorm16EXT && info->type == GL_SHORT));
219*8975f5c5SAndroid Build Coastguard Worker             // Type conversions are not allowed for signed normalized color buffers
220*8975f5c5SAndroid Build Coastguard Worker             return format == GL_RGBA && type == info->type;
221*8975f5c5SAndroid Build Coastguard Worker 
222*8975f5c5SAndroid Build Coastguard Worker         case GL_INT:
223*8975f5c5SAndroid Build Coastguard Worker             return (format == GL_RGBA_INTEGER && type == GL_INT);
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker         case GL_UNSIGNED_INT:
226*8975f5c5SAndroid Build Coastguard Worker             return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
227*8975f5c5SAndroid Build Coastguard Worker 
228*8975f5c5SAndroid Build Coastguard Worker         case GL_FLOAT:
229*8975f5c5SAndroid Build Coastguard Worker             switch (format)
230*8975f5c5SAndroid Build Coastguard Worker             {
231*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA:
232*8975f5c5SAndroid Build Coastguard Worker                     return (type == GL_FLOAT);
233*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_COMPONENT:
234*8975f5c5SAndroid Build Coastguard Worker                     return ValidReadPixelsFloatDepthType(context, info, type);
235*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_STENCIL_OES:
236*8975f5c5SAndroid Build Coastguard Worker                     return context->getExtensions().readDepthStencilNV &&
237*8975f5c5SAndroid Build Coastguard Worker                            type == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && info->stencilBits > 0;
238*8975f5c5SAndroid Build Coastguard Worker                 default:
239*8975f5c5SAndroid Build Coastguard Worker                     return false;
240*8975f5c5SAndroid Build Coastguard Worker             }
241*8975f5c5SAndroid Build Coastguard Worker         default:
242*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
243*8975f5c5SAndroid Build Coastguard Worker             return false;
244*8975f5c5SAndroid Build Coastguard Worker     }
245*8975f5c5SAndroid Build Coastguard Worker }
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureWrapModeValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params,bool restrictedWrapModes)248*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureWrapModeValue(const Context *context,
249*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
250*8975f5c5SAndroid Build Coastguard Worker                                   const ParamType *params,
251*8975f5c5SAndroid Build Coastguard Worker                                   bool restrictedWrapModes)
252*8975f5c5SAndroid Build Coastguard Worker {
253*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
254*8975f5c5SAndroid Build Coastguard Worker     {
255*8975f5c5SAndroid Build Coastguard Worker         case GL_CLAMP_TO_EDGE:
256*8975f5c5SAndroid Build Coastguard Worker             break;
257*8975f5c5SAndroid Build Coastguard Worker 
258*8975f5c5SAndroid Build Coastguard Worker         case GL_CLAMP_TO_BORDER:
259*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureBorderClampAny() &&
260*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
261*8975f5c5SAndroid Build Coastguard Worker             {
262*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
263*8975f5c5SAndroid Build Coastguard Worker                 return false;
264*8975f5c5SAndroid Build Coastguard Worker             }
265*8975f5c5SAndroid Build Coastguard Worker             if (restrictedWrapModes)
266*8975f5c5SAndroid Build Coastguard Worker             {
267*8975f5c5SAndroid Build Coastguard Worker                 // OES_EGL_image_external and ANGLE_texture_rectangle specify this error.
268*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidWrapModeTexture);
269*8975f5c5SAndroid Build Coastguard Worker                 return false;
270*8975f5c5SAndroid Build Coastguard Worker             }
271*8975f5c5SAndroid Build Coastguard Worker             break;
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker         case GL_REPEAT:
274*8975f5c5SAndroid Build Coastguard Worker         case GL_MIRRORED_REPEAT:
275*8975f5c5SAndroid Build Coastguard Worker             if (restrictedWrapModes)
276*8975f5c5SAndroid Build Coastguard Worker             {
277*8975f5c5SAndroid Build Coastguard Worker                 // OES_EGL_image_external and ANGLE_texture_rectangle specify this error.
278*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidWrapModeTexture);
279*8975f5c5SAndroid Build Coastguard Worker                 return false;
280*8975f5c5SAndroid Build Coastguard Worker             }
281*8975f5c5SAndroid Build Coastguard Worker             break;
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker         case GL_MIRROR_CLAMP_TO_EDGE_EXT:
284*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureMirrorClampToEdgeEXT)
285*8975f5c5SAndroid Build Coastguard Worker             {
286*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
287*8975f5c5SAndroid Build Coastguard Worker                 return false;
288*8975f5c5SAndroid Build Coastguard Worker             }
289*8975f5c5SAndroid Build Coastguard Worker             if (restrictedWrapModes)
290*8975f5c5SAndroid Build Coastguard Worker             {
291*8975f5c5SAndroid Build Coastguard Worker                 // OES_EGL_image_external and ANGLE_texture_rectangle specify this error.
292*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidWrapModeTexture);
293*8975f5c5SAndroid Build Coastguard Worker                 return false;
294*8975f5c5SAndroid Build Coastguard Worker             }
295*8975f5c5SAndroid Build Coastguard Worker             break;
296*8975f5c5SAndroid Build Coastguard Worker 
297*8975f5c5SAndroid Build Coastguard Worker         default:
298*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureWrap);
299*8975f5c5SAndroid Build Coastguard Worker             return false;
300*8975f5c5SAndroid Build Coastguard Worker     }
301*8975f5c5SAndroid Build Coastguard Worker 
302*8975f5c5SAndroid Build Coastguard Worker     return true;
303*8975f5c5SAndroid Build Coastguard Worker }
304*8975f5c5SAndroid Build Coastguard Worker 
305*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureMinFilterValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params,bool restrictedMinFilter)306*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMinFilterValue(const Context *context,
307*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
308*8975f5c5SAndroid Build Coastguard Worker                                    const ParamType *params,
309*8975f5c5SAndroid Build Coastguard Worker                                    bool restrictedMinFilter)
310*8975f5c5SAndroid Build Coastguard Worker {
311*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
312*8975f5c5SAndroid Build Coastguard Worker     {
313*8975f5c5SAndroid Build Coastguard Worker         case GL_NEAREST:
314*8975f5c5SAndroid Build Coastguard Worker         case GL_LINEAR:
315*8975f5c5SAndroid Build Coastguard Worker             break;
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker         case GL_NEAREST_MIPMAP_NEAREST:
318*8975f5c5SAndroid Build Coastguard Worker         case GL_LINEAR_MIPMAP_NEAREST:
319*8975f5c5SAndroid Build Coastguard Worker         case GL_NEAREST_MIPMAP_LINEAR:
320*8975f5c5SAndroid Build Coastguard Worker         case GL_LINEAR_MIPMAP_LINEAR:
321*8975f5c5SAndroid Build Coastguard Worker             if (restrictedMinFilter)
322*8975f5c5SAndroid Build Coastguard Worker             {
323*8975f5c5SAndroid Build Coastguard Worker                 // OES_EGL_image_external specifies this error.
324*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFilterTexture);
325*8975f5c5SAndroid Build Coastguard Worker                 return false;
326*8975f5c5SAndroid Build Coastguard Worker             }
327*8975f5c5SAndroid Build Coastguard Worker             break;
328*8975f5c5SAndroid Build Coastguard Worker 
329*8975f5c5SAndroid Build Coastguard Worker         default:
330*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureFilterParam);
331*8975f5c5SAndroid Build Coastguard Worker             return false;
332*8975f5c5SAndroid Build Coastguard Worker     }
333*8975f5c5SAndroid Build Coastguard Worker 
334*8975f5c5SAndroid Build Coastguard Worker     return true;
335*8975f5c5SAndroid Build Coastguard Worker }
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureMagFilterValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)338*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMagFilterValue(const Context *context,
339*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
340*8975f5c5SAndroid Build Coastguard Worker                                    const ParamType *params)
341*8975f5c5SAndroid Build Coastguard Worker {
342*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
343*8975f5c5SAndroid Build Coastguard Worker     {
344*8975f5c5SAndroid Build Coastguard Worker         case GL_NEAREST:
345*8975f5c5SAndroid Build Coastguard Worker         case GL_LINEAR:
346*8975f5c5SAndroid Build Coastguard Worker             break;
347*8975f5c5SAndroid Build Coastguard Worker 
348*8975f5c5SAndroid Build Coastguard Worker         default:
349*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureFilterParam);
350*8975f5c5SAndroid Build Coastguard Worker             return false;
351*8975f5c5SAndroid Build Coastguard Worker     }
352*8975f5c5SAndroid Build Coastguard Worker 
353*8975f5c5SAndroid Build Coastguard Worker     return true;
354*8975f5c5SAndroid Build Coastguard Worker }
355*8975f5c5SAndroid Build Coastguard Worker 
356*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureCompareModeValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)357*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureCompareModeValue(const Context *context,
358*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
359*8975f5c5SAndroid Build Coastguard Worker                                      const ParamType *params)
360*8975f5c5SAndroid Build Coastguard Worker {
361*8975f5c5SAndroid Build Coastguard Worker     // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
362*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
363*8975f5c5SAndroid Build Coastguard Worker     {
364*8975f5c5SAndroid Build Coastguard Worker         case GL_NONE:
365*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPARE_REF_TO_TEXTURE:
366*8975f5c5SAndroid Build Coastguard Worker             break;
367*8975f5c5SAndroid Build Coastguard Worker 
368*8975f5c5SAndroid Build Coastguard Worker         default:
369*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
370*8975f5c5SAndroid Build Coastguard Worker             return false;
371*8975f5c5SAndroid Build Coastguard Worker     }
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker     return true;
374*8975f5c5SAndroid Build Coastguard Worker }
375*8975f5c5SAndroid Build Coastguard Worker 
376*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureCompareFuncValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)377*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureCompareFuncValue(const Context *context,
378*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
379*8975f5c5SAndroid Build Coastguard Worker                                      const ParamType *params)
380*8975f5c5SAndroid Build Coastguard Worker {
381*8975f5c5SAndroid Build Coastguard Worker     // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
382*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
383*8975f5c5SAndroid Build Coastguard Worker     {
384*8975f5c5SAndroid Build Coastguard Worker         case GL_LEQUAL:
385*8975f5c5SAndroid Build Coastguard Worker         case GL_GEQUAL:
386*8975f5c5SAndroid Build Coastguard Worker         case GL_LESS:
387*8975f5c5SAndroid Build Coastguard Worker         case GL_GREATER:
388*8975f5c5SAndroid Build Coastguard Worker         case GL_EQUAL:
389*8975f5c5SAndroid Build Coastguard Worker         case GL_NOTEQUAL:
390*8975f5c5SAndroid Build Coastguard Worker         case GL_ALWAYS:
391*8975f5c5SAndroid Build Coastguard Worker         case GL_NEVER:
392*8975f5c5SAndroid Build Coastguard Worker             break;
393*8975f5c5SAndroid Build Coastguard Worker 
394*8975f5c5SAndroid Build Coastguard Worker         default:
395*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
396*8975f5c5SAndroid Build Coastguard Worker             return false;
397*8975f5c5SAndroid Build Coastguard Worker     }
398*8975f5c5SAndroid Build Coastguard Worker 
399*8975f5c5SAndroid Build Coastguard Worker     return true;
400*8975f5c5SAndroid Build Coastguard Worker }
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureSRGBDecodeValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)403*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureSRGBDecodeValue(const Context *context,
404*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
405*8975f5c5SAndroid Build Coastguard Worker                                     const ParamType *params)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().textureSRGBDecodeEXT)
408*8975f5c5SAndroid Build Coastguard Worker     {
409*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
410*8975f5c5SAndroid Build Coastguard Worker         return false;
411*8975f5c5SAndroid Build Coastguard Worker     }
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
414*8975f5c5SAndroid Build Coastguard Worker     {
415*8975f5c5SAndroid Build Coastguard Worker         case GL_DECODE_EXT:
416*8975f5c5SAndroid Build Coastguard Worker         case GL_SKIP_DECODE_EXT:
417*8975f5c5SAndroid Build Coastguard Worker             break;
418*8975f5c5SAndroid Build Coastguard Worker 
419*8975f5c5SAndroid Build Coastguard Worker         default:
420*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
421*8975f5c5SAndroid Build Coastguard Worker             return false;
422*8975f5c5SAndroid Build Coastguard Worker     }
423*8975f5c5SAndroid Build Coastguard Worker 
424*8975f5c5SAndroid Build Coastguard Worker     return true;
425*8975f5c5SAndroid Build Coastguard Worker }
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTextureSRGBOverrideValue(const Context * context,angle::EntryPoint entryPoint,const ParamType * params)428*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureSRGBOverrideValue(const Context *context,
429*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
430*8975f5c5SAndroid Build Coastguard Worker                                       const ParamType *params)
431*8975f5c5SAndroid Build Coastguard Worker {
432*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().textureFormatSRGBOverrideEXT)
433*8975f5c5SAndroid Build Coastguard Worker     {
434*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
435*8975f5c5SAndroid Build Coastguard Worker         return false;
436*8975f5c5SAndroid Build Coastguard Worker     }
437*8975f5c5SAndroid Build Coastguard Worker 
438*8975f5c5SAndroid Build Coastguard Worker     switch (ConvertToGLenum(params[0]))
439*8975f5c5SAndroid Build Coastguard Worker     {
440*8975f5c5SAndroid Build Coastguard Worker         case GL_SRGB:
441*8975f5c5SAndroid Build Coastguard Worker         case GL_NONE:
442*8975f5c5SAndroid Build Coastguard Worker             break;
443*8975f5c5SAndroid Build Coastguard Worker 
444*8975f5c5SAndroid Build Coastguard Worker         default:
445*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnknownParameter);
446*8975f5c5SAndroid Build Coastguard Worker             return false;
447*8975f5c5SAndroid Build Coastguard Worker     }
448*8975f5c5SAndroid Build Coastguard Worker 
449*8975f5c5SAndroid Build Coastguard Worker     return true;
450*8975f5c5SAndroid Build Coastguard Worker }
451*8975f5c5SAndroid Build Coastguard Worker 
ValidateTextureMaxAnisotropyExtensionEnabled(const Context * context,angle::EntryPoint entryPoint)452*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMaxAnisotropyExtensionEnabled(const Context *context,
453*8975f5c5SAndroid Build Coastguard Worker                                                   angle::EntryPoint entryPoint)
454*8975f5c5SAndroid Build Coastguard Worker {
455*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().textureFilterAnisotropicEXT)
456*8975f5c5SAndroid Build Coastguard Worker     {
457*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
458*8975f5c5SAndroid Build Coastguard Worker         return false;
459*8975f5c5SAndroid Build Coastguard Worker     }
460*8975f5c5SAndroid Build Coastguard Worker 
461*8975f5c5SAndroid Build Coastguard Worker     return true;
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker 
ValidateTextureMaxAnisotropyValue(const Context * context,angle::EntryPoint entryPoint,GLfloat paramValue)464*8975f5c5SAndroid Build Coastguard Worker bool ValidateTextureMaxAnisotropyValue(const Context *context,
465*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
466*8975f5c5SAndroid Build Coastguard Worker                                        GLfloat paramValue)
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
469*8975f5c5SAndroid Build Coastguard Worker     {
470*8975f5c5SAndroid Build Coastguard Worker         return false;
471*8975f5c5SAndroid Build Coastguard Worker     }
472*8975f5c5SAndroid Build Coastguard Worker 
473*8975f5c5SAndroid Build Coastguard Worker     GLfloat largest = context->getCaps().maxTextureAnisotropy;
474*8975f5c5SAndroid Build Coastguard Worker 
475*8975f5c5SAndroid Build Coastguard Worker     if (paramValue < 1 || paramValue > largest)
476*8975f5c5SAndroid Build Coastguard Worker     {
477*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOutsideOfBounds);
478*8975f5c5SAndroid Build Coastguard Worker         return false;
479*8975f5c5SAndroid Build Coastguard Worker     }
480*8975f5c5SAndroid Build Coastguard Worker 
481*8975f5c5SAndroid Build Coastguard Worker     return true;
482*8975f5c5SAndroid Build Coastguard Worker }
483*8975f5c5SAndroid Build Coastguard Worker 
ValidateFragmentShaderColorBufferMaskMatch(const Context * context)484*8975f5c5SAndroid Build Coastguard Worker bool ValidateFragmentShaderColorBufferMaskMatch(const Context *context)
485*8975f5c5SAndroid Build Coastguard Worker {
486*8975f5c5SAndroid Build Coastguard Worker     const auto &glState                 = context->getState();
487*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
488*8975f5c5SAndroid Build Coastguard Worker     const Framebuffer *framebuffer      = glState.getDrawFramebuffer();
489*8975f5c5SAndroid Build Coastguard Worker 
490*8975f5c5SAndroid Build Coastguard Worker     const auto &blendStateExt = glState.getBlendStateExt();
491*8975f5c5SAndroid Build Coastguard Worker     auto drawBufferMask = framebuffer->getDrawBufferMask() & blendStateExt.compareColorMask(0);
492*8975f5c5SAndroid Build Coastguard Worker     auto dualSourceBlendingMask = drawBufferMask & blendStateExt.getEnabledMask() &
493*8975f5c5SAndroid Build Coastguard Worker                                   blendStateExt.getUsesExtendedBlendFactorMask();
494*8975f5c5SAndroid Build Coastguard Worker     auto fragmentOutputMask          = executable->getActiveOutputVariablesMask();
495*8975f5c5SAndroid Build Coastguard Worker     auto fragmentSecondaryOutputMask = executable->getActiveSecondaryOutputVariablesMask();
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     return drawBufferMask == (drawBufferMask & fragmentOutputMask) &&
498*8975f5c5SAndroid Build Coastguard Worker            dualSourceBlendingMask == (dualSourceBlendingMask & fragmentSecondaryOutputMask);
499*8975f5c5SAndroid Build Coastguard Worker }
500*8975f5c5SAndroid Build Coastguard Worker 
ValidateFragmentShaderColorBufferTypeMatch(const Context * context)501*8975f5c5SAndroid Build Coastguard Worker bool ValidateFragmentShaderColorBufferTypeMatch(const Context *context)
502*8975f5c5SAndroid Build Coastguard Worker {
503*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
504*8975f5c5SAndroid Build Coastguard Worker     const Framebuffer *framebuffer      = context->getState().getDrawFramebuffer();
505*8975f5c5SAndroid Build Coastguard Worker 
506*8975f5c5SAndroid Build Coastguard Worker     return ValidateComponentTypeMasks(executable->getFragmentOutputsTypeMask().to_ulong(),
507*8975f5c5SAndroid Build Coastguard Worker                                       framebuffer->getDrawBufferTypeMask().to_ulong(),
508*8975f5c5SAndroid Build Coastguard Worker                                       executable->getActiveOutputVariablesMask().to_ulong(),
509*8975f5c5SAndroid Build Coastguard Worker                                       framebuffer->getDrawBufferMask().to_ulong());
510*8975f5c5SAndroid Build Coastguard Worker }
511*8975f5c5SAndroid Build Coastguard Worker 
ValidateVertexShaderAttributeTypeMatch(const Context * context)512*8975f5c5SAndroid Build Coastguard Worker bool ValidateVertexShaderAttributeTypeMatch(const Context *context)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker     const auto &glState                 = context->getState();
515*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
516*8975f5c5SAndroid Build Coastguard Worker     const VertexArray *vao              = context->getState().getVertexArray();
517*8975f5c5SAndroid Build Coastguard Worker 
518*8975f5c5SAndroid Build Coastguard Worker     if (executable == nullptr)
519*8975f5c5SAndroid Build Coastguard Worker     {
520*8975f5c5SAndroid Build Coastguard Worker         return false;
521*8975f5c5SAndroid Build Coastguard Worker     }
522*8975f5c5SAndroid Build Coastguard Worker 
523*8975f5c5SAndroid Build Coastguard Worker     unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
524*8975f5c5SAndroid Build Coastguard Worker     unsigned long vaoAttribTypeBits          = vao->getAttributesTypeMask().to_ulong();
525*8975f5c5SAndroid Build Coastguard Worker     unsigned long vaoAttribEnabledMask       = vao->getAttributesMask().to_ulong();
526*8975f5c5SAndroid Build Coastguard Worker 
527*8975f5c5SAndroid Build Coastguard Worker     vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex;
528*8975f5c5SAndroid Build Coastguard Worker     vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
529*8975f5c5SAndroid Build Coastguard Worker     vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
530*8975f5c5SAndroid Build Coastguard Worker 
531*8975f5c5SAndroid Build Coastguard Worker     return ValidateComponentTypeMasks(executable->getAttributesTypeMask().to_ulong(),
532*8975f5c5SAndroid Build Coastguard Worker                                       vaoAttribTypeBits, executable->getAttributesMask().to_ulong(),
533*8975f5c5SAndroid Build Coastguard Worker                                       0xFFFF);
534*8975f5c5SAndroid Build Coastguard Worker }
535*8975f5c5SAndroid Build Coastguard Worker 
IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,PrimitiveMode geometryShaderInputPrimitiveType)536*8975f5c5SAndroid Build Coastguard Worker bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
537*8975f5c5SAndroid Build Coastguard Worker                                             PrimitiveMode geometryShaderInputPrimitiveType)
538*8975f5c5SAndroid Build Coastguard Worker {
539*8975f5c5SAndroid Build Coastguard Worker     // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
540*8975f5c5SAndroid Build Coastguard Worker     switch (drawMode)
541*8975f5c5SAndroid Build Coastguard Worker     {
542*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Points:
543*8975f5c5SAndroid Build Coastguard Worker             return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
544*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Lines:
545*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineStrip:
546*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineLoop:
547*8975f5c5SAndroid Build Coastguard Worker             return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
548*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LinesAdjacency:
549*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineStripAdjacency:
550*8975f5c5SAndroid Build Coastguard Worker             return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
551*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Triangles:
552*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleFan:
553*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleStrip:
554*8975f5c5SAndroid Build Coastguard Worker             return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
555*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TrianglesAdjacency:
556*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleStripAdjacency:
557*8975f5c5SAndroid Build Coastguard Worker             return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
558*8975f5c5SAndroid Build Coastguard Worker         default:
559*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
560*8975f5c5SAndroid Build Coastguard Worker             return false;
561*8975f5c5SAndroid Build Coastguard Worker     }
562*8975f5c5SAndroid Build Coastguard Worker }
563*8975f5c5SAndroid Build Coastguard Worker 
564*8975f5c5SAndroid Build Coastguard Worker // GLES1 texture parameters are a small subset of the others
IsValidGLES1TextureParameter(GLenum pname)565*8975f5c5SAndroid Build Coastguard Worker bool IsValidGLES1TextureParameter(GLenum pname)
566*8975f5c5SAndroid Build Coastguard Worker {
567*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
568*8975f5c5SAndroid Build Coastguard Worker     {
569*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAG_FILTER:
570*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_FILTER:
571*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_S:
572*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_T:
573*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_R:
574*8975f5c5SAndroid Build Coastguard Worker         case GL_GENERATE_MIPMAP:
575*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CROP_RECT_OES:
576*8975f5c5SAndroid Build Coastguard Worker             return true;
577*8975f5c5SAndroid Build Coastguard Worker         default:
578*8975f5c5SAndroid Build Coastguard Worker             return false;
579*8975f5c5SAndroid Build Coastguard Worker     }
580*8975f5c5SAndroid Build Coastguard Worker }
581*8975f5c5SAndroid Build Coastguard Worker 
GetSamplerParameterCount(GLenum pname)582*8975f5c5SAndroid Build Coastguard Worker unsigned int GetSamplerParameterCount(GLenum pname)
583*8975f5c5SAndroid Build Coastguard Worker {
584*8975f5c5SAndroid Build Coastguard Worker     return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
585*8975f5c5SAndroid Build Coastguard Worker }
586*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramDrawAdvancedBlendState(const Context * context,const ProgramExecutable & executable)587*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramDrawAdvancedBlendState(const Context *context,
588*8975f5c5SAndroid Build Coastguard Worker                                                   const ProgramExecutable &executable)
589*8975f5c5SAndroid Build Coastguard Worker {
590*8975f5c5SAndroid Build Coastguard Worker     const State &state                                 = context->getState();
591*8975f5c5SAndroid Build Coastguard Worker     const BlendEquationBitSet &supportedBlendEquations = executable.getAdvancedBlendEquations();
592*8975f5c5SAndroid Build Coastguard Worker     const DrawBufferMask &enabledDrawBufferMask        = state.getBlendStateExt().getEnabledMask();
593*8975f5c5SAndroid Build Coastguard Worker 
594*8975f5c5SAndroid Build Coastguard Worker     // Zero (default) means everything is BlendEquationType::Add, so check can be skipped
595*8975f5c5SAndroid Build Coastguard Worker     if (state.getBlendStateExt().getEquationColorBits() != 0)
596*8975f5c5SAndroid Build Coastguard Worker     {
597*8975f5c5SAndroid Build Coastguard Worker         for (size_t blendEnabledBufferIndex : enabledDrawBufferMask)
598*8975f5c5SAndroid Build Coastguard Worker         {
599*8975f5c5SAndroid Build Coastguard Worker             const gl::BlendEquationType enabledBlendEquation =
600*8975f5c5SAndroid Build Coastguard Worker                 state.getBlendStateExt().getEquationColorIndexed(blendEnabledBufferIndex);
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker             if (enabledBlendEquation < gl::BlendEquationType::Multiply ||
603*8975f5c5SAndroid Build Coastguard Worker                 enabledBlendEquation > gl::BlendEquationType::HslLuminosity)
604*8975f5c5SAndroid Build Coastguard Worker             {
605*8975f5c5SAndroid Build Coastguard Worker                 continue;
606*8975f5c5SAndroid Build Coastguard Worker             }
607*8975f5c5SAndroid Build Coastguard Worker 
608*8975f5c5SAndroid Build Coastguard Worker             if (!supportedBlendEquations.test(enabledBlendEquation))
609*8975f5c5SAndroid Build Coastguard Worker             {
610*8975f5c5SAndroid Build Coastguard Worker                 return gl::err::kBlendEquationNotEnabled;
611*8975f5c5SAndroid Build Coastguard Worker             }
612*8975f5c5SAndroid Build Coastguard Worker         }
613*8975f5c5SAndroid Build Coastguard Worker     }
614*8975f5c5SAndroid Build Coastguard Worker 
615*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
616*8975f5c5SAndroid Build Coastguard Worker }
617*8975f5c5SAndroid Build Coastguard Worker 
ShPixelLocalStorageFormatToGLenum(ShPixelLocalStorageFormat format)618*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE GLenum ShPixelLocalStorageFormatToGLenum(ShPixelLocalStorageFormat format)
619*8975f5c5SAndroid Build Coastguard Worker {
620*8975f5c5SAndroid Build Coastguard Worker     switch (format)
621*8975f5c5SAndroid Build Coastguard Worker     {
622*8975f5c5SAndroid Build Coastguard Worker         case ShPixelLocalStorageFormat::NotPLS:
623*8975f5c5SAndroid Build Coastguard Worker             return GL_NONE;
624*8975f5c5SAndroid Build Coastguard Worker         case ShPixelLocalStorageFormat::RGBA8:
625*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8;
626*8975f5c5SAndroid Build Coastguard Worker         case ShPixelLocalStorageFormat::RGBA8I:
627*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8I;
628*8975f5c5SAndroid Build Coastguard Worker         case ShPixelLocalStorageFormat::RGBA8UI:
629*8975f5c5SAndroid Build Coastguard Worker             return GL_RGBA8UI;
630*8975f5c5SAndroid Build Coastguard Worker         case ShPixelLocalStorageFormat::R32UI:
631*8975f5c5SAndroid Build Coastguard Worker             return GL_R32UI;
632*8975f5c5SAndroid Build Coastguard Worker         case ShPixelLocalStorageFormat::R32F:
633*8975f5c5SAndroid Build Coastguard Worker             return GL_R32F;
634*8975f5c5SAndroid Build Coastguard Worker     }
635*8975f5c5SAndroid Build Coastguard Worker     UNREACHABLE();
636*8975f5c5SAndroid Build Coastguard Worker     return GL_NONE;
637*8975f5c5SAndroid Build Coastguard Worker }
638*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramDrawStates(const Context * context,const Extensions & extensions,const ProgramExecutable & executable)639*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE const char *ValidateProgramDrawStates(const Context *context,
640*8975f5c5SAndroid Build Coastguard Worker                                                    const Extensions &extensions,
641*8975f5c5SAndroid Build Coastguard Worker                                                    const ProgramExecutable &executable)
642*8975f5c5SAndroid Build Coastguard Worker {
643*8975f5c5SAndroid Build Coastguard Worker     const State &state = context->getState();
644*8975f5c5SAndroid Build Coastguard Worker     if (extensions.multiviewOVR || extensions.multiview2OVR)
645*8975f5c5SAndroid Build Coastguard Worker     {
646*8975f5c5SAndroid Build Coastguard Worker         const int programNumViews     = executable.usesMultiview() ? executable.getNumViews() : 1;
647*8975f5c5SAndroid Build Coastguard Worker         Framebuffer *framebuffer      = state.getDrawFramebuffer();
648*8975f5c5SAndroid Build Coastguard Worker         const int framebufferNumViews = framebuffer->getNumViews();
649*8975f5c5SAndroid Build Coastguard Worker 
650*8975f5c5SAndroid Build Coastguard Worker         if (framebufferNumViews != programNumViews)
651*8975f5c5SAndroid Build Coastguard Worker         {
652*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kMultiviewMismatch;
653*8975f5c5SAndroid Build Coastguard Worker         }
654*8975f5c5SAndroid Build Coastguard Worker 
655*8975f5c5SAndroid Build Coastguard Worker         if (state.isTransformFeedbackActiveUnpaused() && framebufferNumViews > 1)
656*8975f5c5SAndroid Build Coastguard Worker         {
657*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kMultiviewTransformFeedback;
658*8975f5c5SAndroid Build Coastguard Worker         }
659*8975f5c5SAndroid Build Coastguard Worker 
660*8975f5c5SAndroid Build Coastguard Worker         if (extensions.disjointTimerQueryEXT && framebufferNumViews > 1 &&
661*8975f5c5SAndroid Build Coastguard Worker             state.isQueryActive(QueryType::TimeElapsed))
662*8975f5c5SAndroid Build Coastguard Worker         {
663*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kMultiviewTimerQuery;
664*8975f5c5SAndroid Build Coastguard Worker         }
665*8975f5c5SAndroid Build Coastguard Worker     }
666*8975f5c5SAndroid Build Coastguard Worker 
667*8975f5c5SAndroid Build Coastguard Worker     // Uniform buffer validation
668*8975f5c5SAndroid Build Coastguard Worker     for (size_t uniformBlockIndex = 0; uniformBlockIndex < executable.getUniformBlocks().size();
669*8975f5c5SAndroid Build Coastguard Worker          uniformBlockIndex++)
670*8975f5c5SAndroid Build Coastguard Worker     {
671*8975f5c5SAndroid Build Coastguard Worker         const InterfaceBlock &uniformBlock = executable.getUniformBlockByIndex(uniformBlockIndex);
672*8975f5c5SAndroid Build Coastguard Worker         GLuint blockBinding                = executable.getUniformBlockBinding(uniformBlockIndex);
673*8975f5c5SAndroid Build Coastguard Worker         const OffsetBindingPointer<Buffer> &uniformBuffer =
674*8975f5c5SAndroid Build Coastguard Worker             state.getIndexedUniformBuffer(blockBinding);
675*8975f5c5SAndroid Build Coastguard Worker 
676*8975f5c5SAndroid Build Coastguard Worker         if (uniformBuffer.get() == nullptr && context->isWebGL())
677*8975f5c5SAndroid Build Coastguard Worker         {
678*8975f5c5SAndroid Build Coastguard Worker             // undefined behaviour
679*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kUniformBufferUnbound;
680*8975f5c5SAndroid Build Coastguard Worker         }
681*8975f5c5SAndroid Build Coastguard Worker 
682*8975f5c5SAndroid Build Coastguard Worker         size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
683*8975f5c5SAndroid Build Coastguard Worker         if (uniformBufferSize < uniformBlock.pod.dataSize &&
684*8975f5c5SAndroid Build Coastguard Worker             (context->isWebGL() || context->isBufferAccessValidationEnabled()))
685*8975f5c5SAndroid Build Coastguard Worker         {
686*8975f5c5SAndroid Build Coastguard Worker             // undefined behaviour
687*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kUniformBufferTooSmall;
688*8975f5c5SAndroid Build Coastguard Worker         }
689*8975f5c5SAndroid Build Coastguard Worker 
690*8975f5c5SAndroid Build Coastguard Worker         if (uniformBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
691*8975f5c5SAndroid Build Coastguard Worker         {
692*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kUniformBufferBoundForTransformFeedback;
693*8975f5c5SAndroid Build Coastguard Worker         }
694*8975f5c5SAndroid Build Coastguard Worker     }
695*8975f5c5SAndroid Build Coastguard Worker 
696*8975f5c5SAndroid Build Coastguard Worker     // ANGLE_shader_pixel_local_storage validation.
697*8975f5c5SAndroid Build Coastguard Worker     if (extensions.shaderPixelLocalStorageANGLE)
698*8975f5c5SAndroid Build Coastguard Worker     {
699*8975f5c5SAndroid Build Coastguard Worker         const Framebuffer *framebuffer = state.getDrawFramebuffer();
700*8975f5c5SAndroid Build Coastguard Worker         const PixelLocalStorage *pls   = framebuffer->peekPixelLocalStorage();
701*8975f5c5SAndroid Build Coastguard Worker         const auto &shaderPLSFormats   = executable.getPixelLocalStorageFormats();
702*8975f5c5SAndroid Build Coastguard Worker         size_t activePLSCount          = context->getState().getPixelLocalStorageActivePlanes();
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker         if (shaderPLSFormats.size() > activePLSCount)
705*8975f5c5SAndroid Build Coastguard Worker         {
706*8975f5c5SAndroid Build Coastguard Worker             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that has a
707*8975f5c5SAndroid Build Coastguard Worker             // pixel local uniform bound to an inactive pixel local storage plane.
708*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kPLSDrawProgramPlanesInactive;
709*8975f5c5SAndroid Build Coastguard Worker         }
710*8975f5c5SAndroid Build Coastguard Worker 
711*8975f5c5SAndroid Build Coastguard Worker         if (shaderPLSFormats.size() < activePLSCount)
712*8975f5c5SAndroid Build Coastguard Worker         {
713*8975f5c5SAndroid Build Coastguard Worker             // INVALID_OPERATION is generated if a draw is issued with a fragment shader that does
714*8975f5c5SAndroid Build Coastguard Worker             // _not_ have a pixel local uniform bound to an _active_ pixel local storage plane
715*8975f5c5SAndroid Build Coastguard Worker             // (i.e., the fragment shader must declare uniforms bound to every single active pixel
716*8975f5c5SAndroid Build Coastguard Worker             // local storage plane).
717*8975f5c5SAndroid Build Coastguard Worker             return gl::err::kPLSDrawProgramActivePlanesUnused;
718*8975f5c5SAndroid Build Coastguard Worker         }
719*8975f5c5SAndroid Build Coastguard Worker 
720*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < activePLSCount; ++i)
721*8975f5c5SAndroid Build Coastguard Worker         {
722*8975f5c5SAndroid Build Coastguard Worker             const auto &plsPlane = pls->getPlane(static_cast<GLint>(i));
723*8975f5c5SAndroid Build Coastguard Worker             ASSERT(plsPlane.isActive());
724*8975f5c5SAndroid Build Coastguard Worker             if (shaderPLSFormats[i] == ShPixelLocalStorageFormat::NotPLS)
725*8975f5c5SAndroid Build Coastguard Worker             {
726*8975f5c5SAndroid Build Coastguard Worker                 // INVALID_OPERATION is generated if a draw is issued with a fragment shader that
727*8975f5c5SAndroid Build Coastguard Worker                 // does _not_ have a pixel local uniform bound to an _active_ pixel local storage
728*8975f5c5SAndroid Build Coastguard Worker                 // plane (i.e., the fragment shader must declare uniforms bound to every single
729*8975f5c5SAndroid Build Coastguard Worker                 // active pixel local storage plane).
730*8975f5c5SAndroid Build Coastguard Worker                 return gl::err::kPLSDrawProgramActivePlanesUnused;
731*8975f5c5SAndroid Build Coastguard Worker             }
732*8975f5c5SAndroid Build Coastguard Worker 
733*8975f5c5SAndroid Build Coastguard Worker             if (ShPixelLocalStorageFormatToGLenum(shaderPLSFormats[i]) !=
734*8975f5c5SAndroid Build Coastguard Worker                 plsPlane.getInternalformat())
735*8975f5c5SAndroid Build Coastguard Worker             {
736*8975f5c5SAndroid Build Coastguard Worker                 // INVALID_OPERATION is generated if a draw is issued with a fragment shader that
737*8975f5c5SAndroid Build Coastguard Worker                 // has a pixel local storage uniform whose format layout qualifier does not
738*8975f5c5SAndroid Build Coastguard Worker                 // identically match the internalformat of its associated pixel local storage plane
739*8975f5c5SAndroid Build Coastguard Worker                 // on the current draw framebuffer, as enumerated in Table X.3.
740*8975f5c5SAndroid Build Coastguard Worker                 return gl::err::kPLSDrawProgramFormatMismatch;
741*8975f5c5SAndroid Build Coastguard Worker             }
742*8975f5c5SAndroid Build Coastguard Worker         }
743*8975f5c5SAndroid Build Coastguard Worker     }
744*8975f5c5SAndroid Build Coastguard Worker 
745*8975f5c5SAndroid Build Coastguard Worker     // Enabled blend equation validation
746*8975f5c5SAndroid Build Coastguard Worker     const char *errorString = nullptr;
747*8975f5c5SAndroid Build Coastguard Worker 
748*8975f5c5SAndroid Build Coastguard Worker     if (extensions.blendEquationAdvancedKHR)
749*8975f5c5SAndroid Build Coastguard Worker     {
750*8975f5c5SAndroid Build Coastguard Worker         errorString = ValidateProgramDrawAdvancedBlendState(context, executable);
751*8975f5c5SAndroid Build Coastguard Worker     }
752*8975f5c5SAndroid Build Coastguard Worker 
753*8975f5c5SAndroid Build Coastguard Worker     return errorString;
754*8975f5c5SAndroid Build Coastguard Worker }
755*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
756*8975f5c5SAndroid Build Coastguard Worker 
SetRobustLengthParam(const GLsizei * length,GLsizei value)757*8975f5c5SAndroid Build Coastguard Worker void SetRobustLengthParam(const GLsizei *length, GLsizei value)
758*8975f5c5SAndroid Build Coastguard Worker {
759*8975f5c5SAndroid Build Coastguard Worker     if (length)
760*8975f5c5SAndroid Build Coastguard Worker     {
761*8975f5c5SAndroid Build Coastguard Worker         // Currently we modify robust length parameters in the validation layer. We should be only
762*8975f5c5SAndroid Build Coastguard Worker         // doing this in the Context instead.
763*8975f5c5SAndroid Build Coastguard Worker         // TODO(http://anglebug.com/42263032): Remove when possible.
764*8975f5c5SAndroid Build Coastguard Worker         *const_cast<GLsizei *>(length) = value;
765*8975f5c5SAndroid Build Coastguard Worker     }
766*8975f5c5SAndroid Build Coastguard Worker }
767*8975f5c5SAndroid Build Coastguard Worker 
ValidTextureTarget(const Context * context,TextureType type)768*8975f5c5SAndroid Build Coastguard Worker bool ValidTextureTarget(const Context *context, TextureType type)
769*8975f5c5SAndroid Build Coastguard Worker {
770*8975f5c5SAndroid Build Coastguard Worker     switch (type)
771*8975f5c5SAndroid Build Coastguard Worker     {
772*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2D:
773*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMap:
774*8975f5c5SAndroid Build Coastguard Worker             return true;
775*8975f5c5SAndroid Build Coastguard Worker 
776*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Rectangle:
777*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().textureRectangleANGLE;
778*8975f5c5SAndroid Build Coastguard Worker 
779*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_3D:
780*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0 || context->getExtensions().texture3DOES;
781*8975f5c5SAndroid Build Coastguard Worker 
782*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DArray:
783*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0;
784*8975f5c5SAndroid Build Coastguard Worker 
785*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DMultisample:
786*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_1 ||
787*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureMultisampleANGLE;
788*8975f5c5SAndroid Build Coastguard Worker 
789*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DMultisampleArray:
790*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
791*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureStorageMultisample2dArrayOES;
792*8975f5c5SAndroid Build Coastguard Worker 
793*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMapArray:
794*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
795*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureCubeMapArrayAny();
796*8975f5c5SAndroid Build Coastguard Worker 
797*8975f5c5SAndroid Build Coastguard Worker         case TextureType::VideoImage:
798*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().videoTextureWEBGL;
799*8975f5c5SAndroid Build Coastguard Worker 
800*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Buffer:
801*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
802*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureBufferAny();
803*8975f5c5SAndroid Build Coastguard Worker 
804*8975f5c5SAndroid Build Coastguard Worker         default:
805*8975f5c5SAndroid Build Coastguard Worker             return false;
806*8975f5c5SAndroid Build Coastguard Worker     }
807*8975f5c5SAndroid Build Coastguard Worker }
808*8975f5c5SAndroid Build Coastguard Worker 
ValidTexture2DTarget(const Context * context,TextureType type)809*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture2DTarget(const Context *context, TextureType type)
810*8975f5c5SAndroid Build Coastguard Worker {
811*8975f5c5SAndroid Build Coastguard Worker     switch (type)
812*8975f5c5SAndroid Build Coastguard Worker     {
813*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2D:
814*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMap:
815*8975f5c5SAndroid Build Coastguard Worker             return true;
816*8975f5c5SAndroid Build Coastguard Worker 
817*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Rectangle:
818*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().textureRectangleANGLE;
819*8975f5c5SAndroid Build Coastguard Worker 
820*8975f5c5SAndroid Build Coastguard Worker         default:
821*8975f5c5SAndroid Build Coastguard Worker             return false;
822*8975f5c5SAndroid Build Coastguard Worker     }
823*8975f5c5SAndroid Build Coastguard Worker }
824*8975f5c5SAndroid Build Coastguard Worker 
ValidTexture3DTarget(const Context * context,TextureType target)825*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture3DTarget(const Context *context, TextureType target)
826*8975f5c5SAndroid Build Coastguard Worker {
827*8975f5c5SAndroid Build Coastguard Worker     switch (target)
828*8975f5c5SAndroid Build Coastguard Worker     {
829*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_3D:
830*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DArray:
831*8975f5c5SAndroid Build Coastguard Worker             return (context->getClientMajorVersion() >= 3);
832*8975f5c5SAndroid Build Coastguard Worker 
833*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMapArray:
834*8975f5c5SAndroid Build Coastguard Worker             return (context->getClientVersion() >= Version(3, 2) ||
835*8975f5c5SAndroid Build Coastguard Worker                     context->getExtensions().textureCubeMapArrayAny());
836*8975f5c5SAndroid Build Coastguard Worker 
837*8975f5c5SAndroid Build Coastguard Worker         default:
838*8975f5c5SAndroid Build Coastguard Worker             return false;
839*8975f5c5SAndroid Build Coastguard Worker     }
840*8975f5c5SAndroid Build Coastguard Worker }
841*8975f5c5SAndroid Build Coastguard Worker 
842*8975f5c5SAndroid Build Coastguard Worker // Most texture GL calls are not compatible with external textures, so we have a separate validation
843*8975f5c5SAndroid Build Coastguard Worker // function for use in the GL calls that do
ValidTextureExternalTarget(const Context * context,TextureType target)844*8975f5c5SAndroid Build Coastguard Worker bool ValidTextureExternalTarget(const Context *context, TextureType target)
845*8975f5c5SAndroid Build Coastguard Worker {
846*8975f5c5SAndroid Build Coastguard Worker     return (target == TextureType::External) &&
847*8975f5c5SAndroid Build Coastguard Worker            (context->getExtensions().EGLImageExternalOES ||
848*8975f5c5SAndroid Build Coastguard Worker             context->getExtensions().EGLStreamConsumerExternalNV);
849*8975f5c5SAndroid Build Coastguard Worker }
850*8975f5c5SAndroid Build Coastguard Worker 
ValidTextureExternalTarget(const Context * context,TextureTarget target)851*8975f5c5SAndroid Build Coastguard Worker bool ValidTextureExternalTarget(const Context *context, TextureTarget target)
852*8975f5c5SAndroid Build Coastguard Worker {
853*8975f5c5SAndroid Build Coastguard Worker     return (target == TextureTarget::External) &&
854*8975f5c5SAndroid Build Coastguard Worker            ValidTextureExternalTarget(context, TextureType::External);
855*8975f5c5SAndroid Build Coastguard Worker }
856*8975f5c5SAndroid Build Coastguard Worker 
857*8975f5c5SAndroid Build Coastguard Worker // This function differs from ValidTextureTarget in that the target must be
858*8975f5c5SAndroid Build Coastguard Worker // usable as the destination of a 2D operation-- so a cube face is valid, but
859*8975f5c5SAndroid Build Coastguard Worker // GL_TEXTURE_CUBE_MAP is not.
860*8975f5c5SAndroid Build Coastguard Worker // Note: duplicate of IsInternalTextureTarget
ValidTexture2DDestinationTarget(const Context * context,TextureTarget target)861*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
862*8975f5c5SAndroid Build Coastguard Worker {
863*8975f5c5SAndroid Build Coastguard Worker     switch (target)
864*8975f5c5SAndroid Build Coastguard Worker     {
865*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::_2D:
866*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapNegativeX:
867*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapNegativeY:
868*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapNegativeZ:
869*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapPositiveX:
870*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapPositiveY:
871*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapPositiveZ:
872*8975f5c5SAndroid Build Coastguard Worker             return true;
873*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::Rectangle:
874*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().textureRectangleANGLE;
875*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::VideoImage:
876*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().videoTextureWEBGL;
877*8975f5c5SAndroid Build Coastguard Worker         default:
878*8975f5c5SAndroid Build Coastguard Worker             return false;
879*8975f5c5SAndroid Build Coastguard Worker     }
880*8975f5c5SAndroid Build Coastguard Worker }
881*8975f5c5SAndroid Build Coastguard Worker 
ValidateTransformFeedbackPrimitiveMode(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode transformFeedbackPrimitiveMode,PrimitiveMode renderPrimitiveMode)882*8975f5c5SAndroid Build Coastguard Worker bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
883*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
884*8975f5c5SAndroid Build Coastguard Worker                                             PrimitiveMode transformFeedbackPrimitiveMode,
885*8975f5c5SAndroid Build Coastguard Worker                                             PrimitiveMode renderPrimitiveMode)
886*8975f5c5SAndroid Build Coastguard Worker {
887*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context);
888*8975f5c5SAndroid Build Coastguard Worker 
889*8975f5c5SAndroid Build Coastguard Worker     if ((!context->getExtensions().geometryShaderAny() ||
890*8975f5c5SAndroid Build Coastguard Worker          !context->getExtensions().tessellationShaderAny()) &&
891*8975f5c5SAndroid Build Coastguard Worker         context->getClientVersion() < ES_3_2)
892*8975f5c5SAndroid Build Coastguard Worker     {
893*8975f5c5SAndroid Build Coastguard Worker         // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
894*8975f5c5SAndroid Build Coastguard Worker         // that does not match the current transform feedback object's draw mode (if transform
895*8975f5c5SAndroid Build Coastguard Worker         // feedback is active), (3.0.2, section 2.14, pg 86)
896*8975f5c5SAndroid Build Coastguard Worker         return transformFeedbackPrimitiveMode == renderPrimitiveMode;
897*8975f5c5SAndroid Build Coastguard Worker     }
898*8975f5c5SAndroid Build Coastguard Worker 
899*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable *executable = context->getState().getLinkedProgramExecutable(context);
900*8975f5c5SAndroid Build Coastguard Worker     ASSERT(executable);
901*8975f5c5SAndroid Build Coastguard Worker     if (executable->hasLinkedShaderStage(ShaderType::Geometry))
902*8975f5c5SAndroid Build Coastguard Worker     {
903*8975f5c5SAndroid Build Coastguard Worker         // If geometry shader is active, transform feedback mode must match what is output from this
904*8975f5c5SAndroid Build Coastguard Worker         // stage.
905*8975f5c5SAndroid Build Coastguard Worker         renderPrimitiveMode = executable->getGeometryShaderOutputPrimitiveType();
906*8975f5c5SAndroid Build Coastguard Worker     }
907*8975f5c5SAndroid Build Coastguard Worker     else if (executable->hasLinkedShaderStage(ShaderType::TessEvaluation))
908*8975f5c5SAndroid Build Coastguard Worker     {
909*8975f5c5SAndroid Build Coastguard Worker         // Similarly with tessellation shaders, but only if no geometry shader is present.  With
910*8975f5c5SAndroid Build Coastguard Worker         // tessellation shaders, only triangles are possibly output.
911*8975f5c5SAndroid Build Coastguard Worker         return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles &&
912*8975f5c5SAndroid Build Coastguard Worker                executable->getTessGenMode() == GL_TRIANGLES;
913*8975f5c5SAndroid Build Coastguard Worker     }
914*8975f5c5SAndroid Build Coastguard Worker 
915*8975f5c5SAndroid Build Coastguard Worker     // [GL_EXT_geometry_shader] Table 12.1gs
916*8975f5c5SAndroid Build Coastguard Worker     switch (renderPrimitiveMode)
917*8975f5c5SAndroid Build Coastguard Worker     {
918*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Points:
919*8975f5c5SAndroid Build Coastguard Worker             return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
920*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Lines:
921*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineStrip:
922*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineLoop:
923*8975f5c5SAndroid Build Coastguard Worker             return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
924*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Triangles:
925*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleFan:
926*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleStrip:
927*8975f5c5SAndroid Build Coastguard Worker             return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
928*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Patches:
929*8975f5c5SAndroid Build Coastguard Worker             return transformFeedbackPrimitiveMode == PrimitiveMode::Patches;
930*8975f5c5SAndroid Build Coastguard Worker         default:
931*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
932*8975f5c5SAndroid Build Coastguard Worker             return false;
933*8975f5c5SAndroid Build Coastguard Worker     }
934*8975f5c5SAndroid Build Coastguard Worker }
935*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawElementsInstancedBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount,GLuint baseinstance)936*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawElementsInstancedBase(const Context *context,
937*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
938*8975f5c5SAndroid Build Coastguard Worker                                        PrimitiveMode mode,
939*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei count,
940*8975f5c5SAndroid Build Coastguard Worker                                        DrawElementsType type,
941*8975f5c5SAndroid Build Coastguard Worker                                        const void *indices,
942*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei primcount,
943*8975f5c5SAndroid Build Coastguard Worker                                        GLuint baseinstance)
944*8975f5c5SAndroid Build Coastguard Worker {
945*8975f5c5SAndroid Build Coastguard Worker     if (primcount <= 0)
946*8975f5c5SAndroid Build Coastguard Worker     {
947*8975f5c5SAndroid Build Coastguard Worker         if (primcount < 0)
948*8975f5c5SAndroid Build Coastguard Worker         {
949*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativePrimcount);
950*8975f5c5SAndroid Build Coastguard Worker             return false;
951*8975f5c5SAndroid Build Coastguard Worker         }
952*8975f5c5SAndroid Build Coastguard Worker 
953*8975f5c5SAndroid Build Coastguard Worker         // Early exit.
954*8975f5c5SAndroid Build Coastguard Worker         return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices,
955*8975f5c5SAndroid Build Coastguard Worker                                           primcount);
956*8975f5c5SAndroid Build Coastguard Worker     }
957*8975f5c5SAndroid Build Coastguard Worker 
958*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, primcount))
959*8975f5c5SAndroid Build Coastguard Worker     {
960*8975f5c5SAndroid Build Coastguard Worker         return false;
961*8975f5c5SAndroid Build Coastguard Worker     }
962*8975f5c5SAndroid Build Coastguard Worker 
963*8975f5c5SAndroid Build Coastguard Worker     if (count == 0)
964*8975f5c5SAndroid Build Coastguard Worker     {
965*8975f5c5SAndroid Build Coastguard Worker         // Early exit.
966*8975f5c5SAndroid Build Coastguard Worker         return true;
967*8975f5c5SAndroid Build Coastguard Worker     }
968*8975f5c5SAndroid Build Coastguard Worker 
969*8975f5c5SAndroid Build Coastguard Worker     return ValidateDrawInstancedAttribs(context, entryPoint, primcount, baseinstance);
970*8975f5c5SAndroid Build Coastguard Worker }
971*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawArraysInstancedBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount,GLuint baseinstance)972*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawArraysInstancedBase(const Context *context,
973*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
974*8975f5c5SAndroid Build Coastguard Worker                                      PrimitiveMode mode,
975*8975f5c5SAndroid Build Coastguard Worker                                      GLint first,
976*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei count,
977*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei primcount,
978*8975f5c5SAndroid Build Coastguard Worker                                      GLuint baseinstance)
979*8975f5c5SAndroid Build Coastguard Worker {
980*8975f5c5SAndroid Build Coastguard Worker     if (primcount <= 0)
981*8975f5c5SAndroid Build Coastguard Worker     {
982*8975f5c5SAndroid Build Coastguard Worker         if (primcount < 0)
983*8975f5c5SAndroid Build Coastguard Worker         {
984*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativePrimcount);
985*8975f5c5SAndroid Build Coastguard Worker             return false;
986*8975f5c5SAndroid Build Coastguard Worker         }
987*8975f5c5SAndroid Build Coastguard Worker 
988*8975f5c5SAndroid Build Coastguard Worker         // Early exit.
989*8975f5c5SAndroid Build Coastguard Worker         return ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount);
990*8975f5c5SAndroid Build Coastguard Worker     }
991*8975f5c5SAndroid Build Coastguard Worker 
992*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateDrawArraysCommon(context, entryPoint, mode, first, count, primcount))
993*8975f5c5SAndroid Build Coastguard Worker     {
994*8975f5c5SAndroid Build Coastguard Worker         return false;
995*8975f5c5SAndroid Build Coastguard Worker     }
996*8975f5c5SAndroid Build Coastguard Worker 
997*8975f5c5SAndroid Build Coastguard Worker     if (count == 0)
998*8975f5c5SAndroid Build Coastguard Worker     {
999*8975f5c5SAndroid Build Coastguard Worker         // Early exit.
1000*8975f5c5SAndroid Build Coastguard Worker         return true;
1001*8975f5c5SAndroid Build Coastguard Worker     }
1002*8975f5c5SAndroid Build Coastguard Worker 
1003*8975f5c5SAndroid Build Coastguard Worker     return ValidateDrawInstancedAttribs(context, entryPoint, primcount, baseinstance);
1004*8975f5c5SAndroid Build Coastguard Worker }
1005*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawInstancedANGLE(const Context * context,angle::EntryPoint entryPoint)1006*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint)
1007*8975f5c5SAndroid Build Coastguard Worker {
1008*8975f5c5SAndroid Build Coastguard Worker     // Verify there is at least one active attribute with a divisor of zero
1009*8975f5c5SAndroid Build Coastguard Worker     const State &state                  = context->getState();
1010*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable *executable = state.getLinkedProgramExecutable(context);
1011*8975f5c5SAndroid Build Coastguard Worker 
1012*8975f5c5SAndroid Build Coastguard Worker     if (!executable)
1013*8975f5c5SAndroid Build Coastguard Worker     {
1014*8975f5c5SAndroid Build Coastguard Worker         // No executable means there is no Program/PPO bound, which is undefined behavior, but isn't
1015*8975f5c5SAndroid Build Coastguard Worker         // an error.
1016*8975f5c5SAndroid Build Coastguard Worker         context->getState().getDebug().insertMessage(
1017*8975f5c5SAndroid Build Coastguard Worker             GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, 0, GL_DEBUG_SEVERITY_HIGH,
1018*8975f5c5SAndroid Build Coastguard Worker             std::string("Attempting to draw without a program"), gl::LOG_WARN, entryPoint);
1019*8975f5c5SAndroid Build Coastguard Worker         return true;
1020*8975f5c5SAndroid Build Coastguard Worker     }
1021*8975f5c5SAndroid Build Coastguard Worker 
1022*8975f5c5SAndroid Build Coastguard Worker     const auto &attribs  = state.getVertexArray()->getVertexAttributes();
1023*8975f5c5SAndroid Build Coastguard Worker     const auto &bindings = state.getVertexArray()->getVertexBindings();
1024*8975f5c5SAndroid Build Coastguard Worker     for (size_t attributeIndex = 0; attributeIndex < attribs.size(); attributeIndex++)
1025*8975f5c5SAndroid Build Coastguard Worker     {
1026*8975f5c5SAndroid Build Coastguard Worker         const VertexAttribute &attrib = attribs[attributeIndex];
1027*8975f5c5SAndroid Build Coastguard Worker         const VertexBinding &binding  = bindings[attrib.bindingIndex];
1028*8975f5c5SAndroid Build Coastguard Worker         if (executable->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
1029*8975f5c5SAndroid Build Coastguard Worker         {
1030*8975f5c5SAndroid Build Coastguard Worker             return true;
1031*8975f5c5SAndroid Build Coastguard Worker         }
1032*8975f5c5SAndroid Build Coastguard Worker     }
1033*8975f5c5SAndroid Build Coastguard Worker 
1034*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoZeroDivisor);
1035*8975f5c5SAndroid Build Coastguard Worker     return false;
1036*8975f5c5SAndroid Build Coastguard Worker }
1037*8975f5c5SAndroid Build Coastguard Worker 
ValidTexture3DDestinationTarget(const Context * context,TextureTarget target)1038*8975f5c5SAndroid Build Coastguard Worker bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target)
1039*8975f5c5SAndroid Build Coastguard Worker {
1040*8975f5c5SAndroid Build Coastguard Worker     switch (target)
1041*8975f5c5SAndroid Build Coastguard Worker     {
1042*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::_3D:
1043*8975f5c5SAndroid Build Coastguard Worker             return true;
1044*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::_2DArray:
1045*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= Version(3, 0);
1046*8975f5c5SAndroid Build Coastguard Worker         case TextureTarget::CubeMapArray:
1047*8975f5c5SAndroid Build Coastguard Worker             return (context->getClientVersion() >= Version(3, 2) ||
1048*8975f5c5SAndroid Build Coastguard Worker                     context->getExtensions().textureCubeMapArrayAny());
1049*8975f5c5SAndroid Build Coastguard Worker         default:
1050*8975f5c5SAndroid Build Coastguard Worker             return false;
1051*8975f5c5SAndroid Build Coastguard Worker     }
1052*8975f5c5SAndroid Build Coastguard Worker }
1053*8975f5c5SAndroid Build Coastguard Worker 
ValidTexLevelDestinationTarget(const Context * context,TextureType type)1054*8975f5c5SAndroid Build Coastguard Worker bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
1055*8975f5c5SAndroid Build Coastguard Worker {
1056*8975f5c5SAndroid Build Coastguard Worker     switch (type)
1057*8975f5c5SAndroid Build Coastguard Worker     {
1058*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2D:
1059*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMap:
1060*8975f5c5SAndroid Build Coastguard Worker             return true;
1061*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DArray:
1062*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0;
1063*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DMultisample:
1064*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_1 ||
1065*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureMultisampleANGLE;
1066*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DMultisampleArray:
1067*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
1068*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureStorageMultisample2dArrayOES;
1069*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_3D:
1070*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_0 || context->getExtensions().texture3DOES;
1071*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMapArray:
1072*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
1073*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureCubeMapArrayAny();
1074*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Rectangle:
1075*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().textureRectangleANGLE;
1076*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Buffer:
1077*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
1078*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().textureBufferAny();
1079*8975f5c5SAndroid Build Coastguard Worker         default:
1080*8975f5c5SAndroid Build Coastguard Worker             return false;
1081*8975f5c5SAndroid Build Coastguard Worker     }
1082*8975f5c5SAndroid Build Coastguard Worker }
1083*8975f5c5SAndroid Build Coastguard Worker 
ValidFramebufferTarget(const Context * context,GLenum target)1084*8975f5c5SAndroid Build Coastguard Worker bool ValidFramebufferTarget(const Context *context, GLenum target)
1085*8975f5c5SAndroid Build Coastguard Worker {
1086*8975f5c5SAndroid Build Coastguard Worker     static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
1087*8975f5c5SAndroid Build Coastguard Worker                       GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
1088*8975f5c5SAndroid Build Coastguard Worker                   "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
1089*8975f5c5SAndroid Build Coastguard Worker 
1090*8975f5c5SAndroid Build Coastguard Worker     switch (target)
1091*8975f5c5SAndroid Build Coastguard Worker     {
1092*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER:
1093*8975f5c5SAndroid Build Coastguard Worker             return true;
1094*8975f5c5SAndroid Build Coastguard Worker 
1095*8975f5c5SAndroid Build Coastguard Worker         case GL_READ_FRAMEBUFFER:
1096*8975f5c5SAndroid Build Coastguard Worker         case GL_DRAW_FRAMEBUFFER:
1097*8975f5c5SAndroid Build Coastguard Worker             return (context->getExtensions().framebufferBlitAny() ||
1098*8975f5c5SAndroid Build Coastguard Worker                     context->getClientMajorVersion() >= 3);
1099*8975f5c5SAndroid Build Coastguard Worker 
1100*8975f5c5SAndroid Build Coastguard Worker         default:
1101*8975f5c5SAndroid Build Coastguard Worker             return false;
1102*8975f5c5SAndroid Build Coastguard Worker     }
1103*8975f5c5SAndroid Build Coastguard Worker }
1104*8975f5c5SAndroid Build Coastguard Worker 
ValidMipLevel(const Context * context,TextureType type,GLint level)1105*8975f5c5SAndroid Build Coastguard Worker bool ValidMipLevel(const Context *context, TextureType type, GLint level)
1106*8975f5c5SAndroid Build Coastguard Worker {
1107*8975f5c5SAndroid Build Coastguard Worker     const auto &caps = context->getCaps();
1108*8975f5c5SAndroid Build Coastguard Worker     int maxDimension = 0;
1109*8975f5c5SAndroid Build Coastguard Worker     switch (type)
1110*8975f5c5SAndroid Build Coastguard Worker     {
1111*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2D:
1112*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DArray:
1113*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max2DTextureSize;
1114*8975f5c5SAndroid Build Coastguard Worker             break;
1115*8975f5c5SAndroid Build Coastguard Worker 
1116*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMap:
1117*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMapArray:
1118*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.maxCubeMapTextureSize;
1119*8975f5c5SAndroid Build Coastguard Worker             break;
1120*8975f5c5SAndroid Build Coastguard Worker 
1121*8975f5c5SAndroid Build Coastguard Worker         case TextureType::External:
1122*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Rectangle:
1123*8975f5c5SAndroid Build Coastguard Worker         case TextureType::VideoImage:
1124*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Buffer:
1125*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DMultisample:
1126*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DMultisampleArray:
1127*8975f5c5SAndroid Build Coastguard Worker             return level == 0;
1128*8975f5c5SAndroid Build Coastguard Worker 
1129*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_3D:
1130*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max3DTextureSize;
1131*8975f5c5SAndroid Build Coastguard Worker             break;
1132*8975f5c5SAndroid Build Coastguard Worker 
1133*8975f5c5SAndroid Build Coastguard Worker         default:
1134*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
1135*8975f5c5SAndroid Build Coastguard Worker     }
1136*8975f5c5SAndroid Build Coastguard Worker 
1137*8975f5c5SAndroid Build Coastguard Worker     return level <= log2(maxDimension) && level >= 0;
1138*8975f5c5SAndroid Build Coastguard Worker }
1139*8975f5c5SAndroid Build Coastguard Worker 
ValidImageSizeParameters(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLint level,GLsizei width,GLsizei height,GLsizei depth,bool isSubImage)1140*8975f5c5SAndroid Build Coastguard Worker bool ValidImageSizeParameters(const Context *context,
1141*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
1142*8975f5c5SAndroid Build Coastguard Worker                               TextureType target,
1143*8975f5c5SAndroid Build Coastguard Worker                               GLint level,
1144*8975f5c5SAndroid Build Coastguard Worker                               GLsizei width,
1145*8975f5c5SAndroid Build Coastguard Worker                               GLsizei height,
1146*8975f5c5SAndroid Build Coastguard Worker                               GLsizei depth,
1147*8975f5c5SAndroid Build Coastguard Worker                               bool isSubImage)
1148*8975f5c5SAndroid Build Coastguard Worker {
1149*8975f5c5SAndroid Build Coastguard Worker     if (width < 0 || height < 0 || depth < 0)
1150*8975f5c5SAndroid Build Coastguard Worker     {
1151*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
1152*8975f5c5SAndroid Build Coastguard Worker         return false;
1153*8975f5c5SAndroid Build Coastguard Worker     }
1154*8975f5c5SAndroid Build Coastguard Worker     // TexSubImage parameters can be NPOT without textureNPOT extension,
1155*8975f5c5SAndroid Build Coastguard Worker     // as long as the destination texture is POT.
1156*8975f5c5SAndroid Build Coastguard Worker     bool hasNPOTSupport =
1157*8975f5c5SAndroid Build Coastguard Worker         context->getExtensions().textureNpotOES || context->getClientVersion() >= Version(3, 0);
1158*8975f5c5SAndroid Build Coastguard Worker     if (!isSubImage && !hasNPOTSupport &&
1159*8975f5c5SAndroid Build Coastguard Worker         (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
1160*8975f5c5SAndroid Build Coastguard Worker     {
1161*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureNotPow2);
1162*8975f5c5SAndroid Build Coastguard Worker         return false;
1163*8975f5c5SAndroid Build Coastguard Worker     }
1164*8975f5c5SAndroid Build Coastguard Worker 
1165*8975f5c5SAndroid Build Coastguard Worker     if (!ValidMipLevel(context, target, level))
1166*8975f5c5SAndroid Build Coastguard Worker     {
1167*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
1168*8975f5c5SAndroid Build Coastguard Worker         return false;
1169*8975f5c5SAndroid Build Coastguard Worker     }
1170*8975f5c5SAndroid Build Coastguard Worker 
1171*8975f5c5SAndroid Build Coastguard Worker     return true;
1172*8975f5c5SAndroid Build Coastguard Worker }
1173*8975f5c5SAndroid Build Coastguard Worker 
ValidCompressedBaseLevel(GLsizei size,GLuint blockSize,GLint level)1174*8975f5c5SAndroid Build Coastguard Worker bool ValidCompressedBaseLevel(GLsizei size, GLuint blockSize, GLint level)
1175*8975f5c5SAndroid Build Coastguard Worker {
1176*8975f5c5SAndroid Build Coastguard Worker     // Already checked in ValidMipLevel.
1177*8975f5c5SAndroid Build Coastguard Worker     ASSERT(level < 32);
1178*8975f5c5SAndroid Build Coastguard Worker     // This function is used only for 4x4 BC formats.
1179*8975f5c5SAndroid Build Coastguard Worker     ASSERT(blockSize == 4);
1180*8975f5c5SAndroid Build Coastguard Worker     // Use the constant value to avoid division.
1181*8975f5c5SAndroid Build Coastguard Worker     return ((size << level) % 4) == 0;
1182*8975f5c5SAndroid Build Coastguard Worker }
1183*8975f5c5SAndroid Build Coastguard Worker 
ValidCompressedImageSize(const Context * context,GLenum internalFormat,GLint level,GLsizei width,GLsizei height,GLsizei depth)1184*8975f5c5SAndroid Build Coastguard Worker bool ValidCompressedImageSize(const Context *context,
1185*8975f5c5SAndroid Build Coastguard Worker                               GLenum internalFormat,
1186*8975f5c5SAndroid Build Coastguard Worker                               GLint level,
1187*8975f5c5SAndroid Build Coastguard Worker                               GLsizei width,
1188*8975f5c5SAndroid Build Coastguard Worker                               GLsizei height,
1189*8975f5c5SAndroid Build Coastguard Worker                               GLsizei depth)
1190*8975f5c5SAndroid Build Coastguard Worker {
1191*8975f5c5SAndroid Build Coastguard Worker     if (width < 0 || height < 0)
1192*8975f5c5SAndroid Build Coastguard Worker     {
1193*8975f5c5SAndroid Build Coastguard Worker         return false;
1194*8975f5c5SAndroid Build Coastguard Worker     }
1195*8975f5c5SAndroid Build Coastguard Worker 
1196*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
1197*8975f5c5SAndroid Build Coastguard Worker 
1198*8975f5c5SAndroid Build Coastguard Worker     if (!formatInfo.compressed && !formatInfo.paletted)
1199*8975f5c5SAndroid Build Coastguard Worker     {
1200*8975f5c5SAndroid Build Coastguard Worker         return false;
1201*8975f5c5SAndroid Build Coastguard Worker     }
1202*8975f5c5SAndroid Build Coastguard Worker 
1203*8975f5c5SAndroid Build Coastguard Worker     // A texture format can not be both block-compressed and paletted
1204*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!(formatInfo.compressed && formatInfo.paletted));
1205*8975f5c5SAndroid Build Coastguard Worker 
1206*8975f5c5SAndroid Build Coastguard Worker     if (formatInfo.compressed)
1207*8975f5c5SAndroid Build Coastguard Worker     {
1208*8975f5c5SAndroid Build Coastguard Worker         // Only PVRTC1 requires dimensions to be powers of two
1209*8975f5c5SAndroid Build Coastguard Worker         if (IsPVRTC1Format(internalFormat))
1210*8975f5c5SAndroid Build Coastguard Worker         {
1211*8975f5c5SAndroid Build Coastguard Worker             if (!isPow2(width) || !isPow2(height))
1212*8975f5c5SAndroid Build Coastguard Worker             {
1213*8975f5c5SAndroid Build Coastguard Worker                 return false;
1214*8975f5c5SAndroid Build Coastguard Worker             }
1215*8975f5c5SAndroid Build Coastguard Worker 
1216*8975f5c5SAndroid Build Coastguard Worker             if (context->getLimitations().squarePvrtc1)
1217*8975f5c5SAndroid Build Coastguard Worker             {
1218*8975f5c5SAndroid Build Coastguard Worker                 if (width != height)
1219*8975f5c5SAndroid Build Coastguard Worker                 {
1220*8975f5c5SAndroid Build Coastguard Worker                     return false;
1221*8975f5c5SAndroid Build Coastguard Worker                 }
1222*8975f5c5SAndroid Build Coastguard Worker             }
1223*8975f5c5SAndroid Build Coastguard Worker         }
1224*8975f5c5SAndroid Build Coastguard Worker 
1225*8975f5c5SAndroid Build Coastguard Worker         if (CompressedTextureFormatRequiresExactSize(internalFormat))
1226*8975f5c5SAndroid Build Coastguard Worker         {
1227*8975f5c5SAndroid Build Coastguard Worker             // In WebGL compatibility mode and D3D, enforce that the base level implied
1228*8975f5c5SAndroid Build Coastguard Worker             // by the compressed texture's mip level would conform to the block
1229*8975f5c5SAndroid Build Coastguard Worker             // size.
1230*8975f5c5SAndroid Build Coastguard Worker             if (context->isWebGL() ||
1231*8975f5c5SAndroid Build Coastguard Worker                 context->getLimitations().compressedBaseMipLevelMultipleOfFour)
1232*8975f5c5SAndroid Build Coastguard Worker             {
1233*8975f5c5SAndroid Build Coastguard Worker                 // This check is performed only for BC formats.
1234*8975f5c5SAndroid Build Coastguard Worker                 ASSERT(formatInfo.compressedBlockDepth == 1);
1235*8975f5c5SAndroid Build Coastguard Worker                 if (!ValidCompressedBaseLevel(width, formatInfo.compressedBlockWidth, level) ||
1236*8975f5c5SAndroid Build Coastguard Worker                     !ValidCompressedBaseLevel(height, formatInfo.compressedBlockHeight, level))
1237*8975f5c5SAndroid Build Coastguard Worker                 {
1238*8975f5c5SAndroid Build Coastguard Worker                     return false;
1239*8975f5c5SAndroid Build Coastguard Worker                 }
1240*8975f5c5SAndroid Build Coastguard Worker             }
1241*8975f5c5SAndroid Build Coastguard Worker             // non-WebGL and non-D3D check is not necessary for the following formats
1242*8975f5c5SAndroid Build Coastguard Worker             // From EXT_texture_compression_s3tc specification:
1243*8975f5c5SAndroid Build Coastguard Worker             // If the width or height is not a multiple of four, there will be 4x4 blocks at the
1244*8975f5c5SAndroid Build Coastguard Worker             // edge of the image that contain "extra" texels that are not part of the image. From
1245*8975f5c5SAndroid Build Coastguard Worker             // EXT_texture_compression_bptc & EXT_texture_compression_rgtc specification: If an
1246*8975f5c5SAndroid Build Coastguard Worker             // RGTC/BPTC image has a width or height that is not a multiple of four, the data
1247*8975f5c5SAndroid Build Coastguard Worker             // corresponding to texels outside the image are irrelevant and undefined.
1248*8975f5c5SAndroid Build Coastguard Worker         }
1249*8975f5c5SAndroid Build Coastguard Worker     }
1250*8975f5c5SAndroid Build Coastguard Worker 
1251*8975f5c5SAndroid Build Coastguard Worker     if (formatInfo.paletted)
1252*8975f5c5SAndroid Build Coastguard Worker     {
1253*8975f5c5SAndroid Build Coastguard Worker         // TODO(http://anglebug.com/42266155): multi-level paletted images
1254*8975f5c5SAndroid Build Coastguard Worker         if (level != 0)
1255*8975f5c5SAndroid Build Coastguard Worker         {
1256*8975f5c5SAndroid Build Coastguard Worker             return false;
1257*8975f5c5SAndroid Build Coastguard Worker         }
1258*8975f5c5SAndroid Build Coastguard Worker 
1259*8975f5c5SAndroid Build Coastguard Worker         if (!isPow2(width) || !isPow2(height))
1260*8975f5c5SAndroid Build Coastguard Worker         {
1261*8975f5c5SAndroid Build Coastguard Worker             return false;
1262*8975f5c5SAndroid Build Coastguard Worker         }
1263*8975f5c5SAndroid Build Coastguard Worker     }
1264*8975f5c5SAndroid Build Coastguard Worker 
1265*8975f5c5SAndroid Build Coastguard Worker     return true;
1266*8975f5c5SAndroid Build Coastguard Worker }
1267*8975f5c5SAndroid Build Coastguard Worker 
ValidCompressedSubImageSize(const Context * context,GLenum internalFormat,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,size_t textureWidth,size_t textureHeight,size_t textureDepth)1268*8975f5c5SAndroid Build Coastguard Worker bool ValidCompressedSubImageSize(const Context *context,
1269*8975f5c5SAndroid Build Coastguard Worker                                  GLenum internalFormat,
1270*8975f5c5SAndroid Build Coastguard Worker                                  GLint xoffset,
1271*8975f5c5SAndroid Build Coastguard Worker                                  GLint yoffset,
1272*8975f5c5SAndroid Build Coastguard Worker                                  GLint zoffset,
1273*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei width,
1274*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei height,
1275*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei depth,
1276*8975f5c5SAndroid Build Coastguard Worker                                  size_t textureWidth,
1277*8975f5c5SAndroid Build Coastguard Worker                                  size_t textureHeight,
1278*8975f5c5SAndroid Build Coastguard Worker                                  size_t textureDepth)
1279*8975f5c5SAndroid Build Coastguard Worker {
1280*8975f5c5SAndroid Build Coastguard Worker     // Passing non-compressed internal format to sub-image compressed entry points generates
1281*8975f5c5SAndroid Build Coastguard Worker     // INVALID_OPERATION, so check it here.
1282*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
1283*8975f5c5SAndroid Build Coastguard Worker     if (!formatInfo.compressed)
1284*8975f5c5SAndroid Build Coastguard Worker     {
1285*8975f5c5SAndroid Build Coastguard Worker         return false;
1286*8975f5c5SAndroid Build Coastguard Worker     }
1287*8975f5c5SAndroid Build Coastguard Worker 
1288*8975f5c5SAndroid Build Coastguard Worker     // Negative dimensions already checked in ValidImageSizeParameters called by
1289*8975f5c5SAndroid Build Coastguard Worker     // ValidateES2TexImageParametersBase or ValidateES3TexImageParametersBase.
1290*8975f5c5SAndroid Build Coastguard Worker     ASSERT(width >= 0 && height >= 0 && depth >= 0);
1291*8975f5c5SAndroid Build Coastguard Worker 
1292*8975f5c5SAndroid Build Coastguard Worker     // Negative and overflowed offsets already checked in ValidateES2TexImageParametersBase or
1293*8975f5c5SAndroid Build Coastguard Worker     // ValidateES3TexImageParametersBase.
1294*8975f5c5SAndroid Build Coastguard Worker     ASSERT(xoffset >= 0 && yoffset >= 0 && zoffset >= 0);
1295*8975f5c5SAndroid Build Coastguard Worker     ASSERT(std::numeric_limits<GLsizei>::max() - xoffset >= width &&
1296*8975f5c5SAndroid Build Coastguard Worker            std::numeric_limits<GLsizei>::max() - yoffset >= height &&
1297*8975f5c5SAndroid Build Coastguard Worker            std::numeric_limits<GLsizei>::max() - zoffset >= depth);
1298*8975f5c5SAndroid Build Coastguard Worker 
1299*8975f5c5SAndroid Build Coastguard Worker     // Ensure that format's block dimensions are set.
1300*8975f5c5SAndroid Build Coastguard Worker     ASSERT(formatInfo.compressedBlockWidth > 0 && formatInfo.compressedBlockHeight > 0 &&
1301*8975f5c5SAndroid Build Coastguard Worker            formatInfo.compressedBlockDepth > 0);
1302*8975f5c5SAndroid Build Coastguard Worker 
1303*8975f5c5SAndroid Build Coastguard Worker     // Check if the whole image is being replaced. For 2D texture blocks, zoffset and depth do not
1304*8975f5c5SAndroid Build Coastguard Worker     // affect whether the replaced region fills the entire image.
1305*8975f5c5SAndroid Build Coastguard Worker     if ((xoffset == 0 && static_cast<size_t>(width) == textureWidth) &&
1306*8975f5c5SAndroid Build Coastguard Worker         (yoffset == 0 && static_cast<size_t>(height) == textureHeight) &&
1307*8975f5c5SAndroid Build Coastguard Worker         ((zoffset == 0 && static_cast<size_t>(depth) == textureDepth) ||
1308*8975f5c5SAndroid Build Coastguard Worker          formatInfo.compressedBlockDepth == 1))
1309*8975f5c5SAndroid Build Coastguard Worker     {
1310*8975f5c5SAndroid Build Coastguard Worker         // All compressed formats support whole image replacement, early pass.
1311*8975f5c5SAndroid Build Coastguard Worker         return true;
1312*8975f5c5SAndroid Build Coastguard Worker     }
1313*8975f5c5SAndroid Build Coastguard Worker 
1314*8975f5c5SAndroid Build Coastguard Worker     // The replaced region does not match the image size. Fail if the format does not support
1315*8975f5c5SAndroid Build Coastguard Worker     // partial updates.
1316*8975f5c5SAndroid Build Coastguard Worker     if (CompressedFormatRequiresWholeImage(internalFormat))
1317*8975f5c5SAndroid Build Coastguard Worker     {
1318*8975f5c5SAndroid Build Coastguard Worker         return false;
1319*8975f5c5SAndroid Build Coastguard Worker     }
1320*8975f5c5SAndroid Build Coastguard Worker 
1321*8975f5c5SAndroid Build Coastguard Worker     // The format supports partial updates. Check that the origin of the replaced region is aligned
1322*8975f5c5SAndroid Build Coastguard Worker     // to block boundaries.
1323*8975f5c5SAndroid Build Coastguard Worker     if (xoffset % formatInfo.compressedBlockWidth != 0 ||
1324*8975f5c5SAndroid Build Coastguard Worker         yoffset % formatInfo.compressedBlockHeight != 0 ||
1325*8975f5c5SAndroid Build Coastguard Worker         zoffset % formatInfo.compressedBlockDepth != 0)
1326*8975f5c5SAndroid Build Coastguard Worker     {
1327*8975f5c5SAndroid Build Coastguard Worker         return false;
1328*8975f5c5SAndroid Build Coastguard Worker     }
1329*8975f5c5SAndroid Build Coastguard Worker 
1330*8975f5c5SAndroid Build Coastguard Worker     // The replaced region dimensions must either be multiples of the block dimensions or exactly
1331*8975f5c5SAndroid Build Coastguard Worker     // reach the image boundaries.
1332*8975f5c5SAndroid Build Coastguard Worker     return (static_cast<size_t>(xoffset + width) == textureWidth ||
1333*8975f5c5SAndroid Build Coastguard Worker             width % formatInfo.compressedBlockWidth == 0) &&
1334*8975f5c5SAndroid Build Coastguard Worker            (static_cast<size_t>(yoffset + height) == textureHeight ||
1335*8975f5c5SAndroid Build Coastguard Worker             height % formatInfo.compressedBlockHeight == 0) &&
1336*8975f5c5SAndroid Build Coastguard Worker            (static_cast<size_t>(zoffset + depth) == textureDepth ||
1337*8975f5c5SAndroid Build Coastguard Worker             depth % formatInfo.compressedBlockDepth == 0);
1338*8975f5c5SAndroid Build Coastguard Worker }
1339*8975f5c5SAndroid Build Coastguard Worker 
ValidImageDataSize(const Context * context,angle::EntryPoint entryPoint,TextureType texType,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels,GLsizei imageSize)1340*8975f5c5SAndroid Build Coastguard Worker bool ValidImageDataSize(const Context *context,
1341*8975f5c5SAndroid Build Coastguard Worker                         angle::EntryPoint entryPoint,
1342*8975f5c5SAndroid Build Coastguard Worker                         TextureType texType,
1343*8975f5c5SAndroid Build Coastguard Worker                         GLsizei width,
1344*8975f5c5SAndroid Build Coastguard Worker                         GLsizei height,
1345*8975f5c5SAndroid Build Coastguard Worker                         GLsizei depth,
1346*8975f5c5SAndroid Build Coastguard Worker                         GLenum format,
1347*8975f5c5SAndroid Build Coastguard Worker                         GLenum type,
1348*8975f5c5SAndroid Build Coastguard Worker                         const void *pixels,
1349*8975f5c5SAndroid Build Coastguard Worker                         GLsizei imageSize)
1350*8975f5c5SAndroid Build Coastguard Worker {
1351*8975f5c5SAndroid Build Coastguard Worker     Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
1352*8975f5c5SAndroid Build Coastguard Worker     if (pixelUnpackBuffer == nullptr && imageSize < 0)
1353*8975f5c5SAndroid Build Coastguard Worker     {
1354*8975f5c5SAndroid Build Coastguard Worker         // Checks are not required
1355*8975f5c5SAndroid Build Coastguard Worker         return true;
1356*8975f5c5SAndroid Build Coastguard Worker     }
1357*8975f5c5SAndroid Build Coastguard Worker 
1358*8975f5c5SAndroid Build Coastguard Worker     // ...the data would be unpacked from the buffer object such that the memory reads required
1359*8975f5c5SAndroid Build Coastguard Worker     // would exceed the data store size.
1360*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
1361*8975f5c5SAndroid Build Coastguard Worker     if (formatInfo.internalFormat == GL_NONE)
1362*8975f5c5SAndroid Build Coastguard Worker     {
1363*8975f5c5SAndroid Build Coastguard Worker         UNREACHABLE();
1364*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalErrorFormatNotFound);
1365*8975f5c5SAndroid Build Coastguard Worker         return false;
1366*8975f5c5SAndroid Build Coastguard Worker     }
1367*8975f5c5SAndroid Build Coastguard Worker     const Extents size(width, height, depth);
1368*8975f5c5SAndroid Build Coastguard Worker     const auto &unpack = context->getState().getUnpackState();
1369*8975f5c5SAndroid Build Coastguard Worker 
1370*8975f5c5SAndroid Build Coastguard Worker     bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
1371*8975f5c5SAndroid Build Coastguard Worker     GLuint endByte  = 0;
1372*8975f5c5SAndroid Build Coastguard Worker     if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
1373*8975f5c5SAndroid Build Coastguard Worker     {
1374*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
1375*8975f5c5SAndroid Build Coastguard Worker         return false;
1376*8975f5c5SAndroid Build Coastguard Worker     }
1377*8975f5c5SAndroid Build Coastguard Worker 
1378*8975f5c5SAndroid Build Coastguard Worker     if (pixelUnpackBuffer)
1379*8975f5c5SAndroid Build Coastguard Worker     {
1380*8975f5c5SAndroid Build Coastguard Worker         CheckedNumeric<size_t> checkedEndByte(endByte);
1381*8975f5c5SAndroid Build Coastguard Worker         CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
1382*8975f5c5SAndroid Build Coastguard Worker         checkedEndByte += checkedOffset;
1383*8975f5c5SAndroid Build Coastguard Worker 
1384*8975f5c5SAndroid Build Coastguard Worker         if (!checkedEndByte.IsValid() ||
1385*8975f5c5SAndroid Build Coastguard Worker             (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
1386*8975f5c5SAndroid Build Coastguard Worker         {
1387*8975f5c5SAndroid Build Coastguard Worker             // Overflow past the end of the buffer
1388*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
1389*8975f5c5SAndroid Build Coastguard Worker             return false;
1390*8975f5c5SAndroid Build Coastguard Worker         }
1391*8975f5c5SAndroid Build Coastguard Worker         if (pixelUnpackBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
1392*8975f5c5SAndroid Build Coastguard Worker         {
1393*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1394*8975f5c5SAndroid Build Coastguard Worker                                    kPixelUnpackBufferBoundForTransformFeedback);
1395*8975f5c5SAndroid Build Coastguard Worker             return false;
1396*8975f5c5SAndroid Build Coastguard Worker         }
1397*8975f5c5SAndroid Build Coastguard Worker     }
1398*8975f5c5SAndroid Build Coastguard Worker     else
1399*8975f5c5SAndroid Build Coastguard Worker     {
1400*8975f5c5SAndroid Build Coastguard Worker         ASSERT(imageSize >= 0);
1401*8975f5c5SAndroid Build Coastguard Worker         if (pixels == nullptr && imageSize != 0)
1402*8975f5c5SAndroid Build Coastguard Worker         {
1403*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImageSizeMustBeZero);
1404*8975f5c5SAndroid Build Coastguard Worker             return false;
1405*8975f5c5SAndroid Build Coastguard Worker         }
1406*8975f5c5SAndroid Build Coastguard Worker 
1407*8975f5c5SAndroid Build Coastguard Worker         if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
1408*8975f5c5SAndroid Build Coastguard Worker         {
1409*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImageSizeTooSmall);
1410*8975f5c5SAndroid Build Coastguard Worker             return false;
1411*8975f5c5SAndroid Build Coastguard Worker         }
1412*8975f5c5SAndroid Build Coastguard Worker     }
1413*8975f5c5SAndroid Build Coastguard Worker 
1414*8975f5c5SAndroid Build Coastguard Worker     return true;
1415*8975f5c5SAndroid Build Coastguard Worker }
1416*8975f5c5SAndroid Build Coastguard Worker 
ValidQueryType(const Context * context,QueryType queryType)1417*8975f5c5SAndroid Build Coastguard Worker bool ValidQueryType(const Context *context, QueryType queryType)
1418*8975f5c5SAndroid Build Coastguard Worker {
1419*8975f5c5SAndroid Build Coastguard Worker     switch (queryType)
1420*8975f5c5SAndroid Build Coastguard Worker     {
1421*8975f5c5SAndroid Build Coastguard Worker         case QueryType::AnySamples:
1422*8975f5c5SAndroid Build Coastguard Worker         case QueryType::AnySamplesConservative:
1423*8975f5c5SAndroid Build Coastguard Worker             return context->getClientMajorVersion() >= 3 ||
1424*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().occlusionQueryBooleanEXT;
1425*8975f5c5SAndroid Build Coastguard Worker         case QueryType::TransformFeedbackPrimitivesWritten:
1426*8975f5c5SAndroid Build Coastguard Worker             return (context->getClientMajorVersion() >= 3);
1427*8975f5c5SAndroid Build Coastguard Worker         case QueryType::TimeElapsed:
1428*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().disjointTimerQueryEXT;
1429*8975f5c5SAndroid Build Coastguard Worker         case QueryType::CommandsCompleted:
1430*8975f5c5SAndroid Build Coastguard Worker             return context->getExtensions().syncQueryCHROMIUM;
1431*8975f5c5SAndroid Build Coastguard Worker         case QueryType::PrimitivesGenerated:
1432*8975f5c5SAndroid Build Coastguard Worker             return context->getClientVersion() >= ES_3_2 ||
1433*8975f5c5SAndroid Build Coastguard Worker                    context->getExtensions().geometryShaderAny();
1434*8975f5c5SAndroid Build Coastguard Worker         default:
1435*8975f5c5SAndroid Build Coastguard Worker             return false;
1436*8975f5c5SAndroid Build Coastguard Worker     }
1437*8975f5c5SAndroid Build Coastguard Worker }
1438*8975f5c5SAndroid Build Coastguard Worker 
ValidateWebGLVertexAttribPointer(const Context * context,angle::EntryPoint entryPoint,VertexAttribType type,GLboolean normalized,GLsizei stride,const void * ptr,bool pureInteger)1439*8975f5c5SAndroid Build Coastguard Worker bool ValidateWebGLVertexAttribPointer(const Context *context,
1440*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
1441*8975f5c5SAndroid Build Coastguard Worker                                       VertexAttribType type,
1442*8975f5c5SAndroid Build Coastguard Worker                                       GLboolean normalized,
1443*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei stride,
1444*8975f5c5SAndroid Build Coastguard Worker                                       const void *ptr,
1445*8975f5c5SAndroid Build Coastguard Worker                                       bool pureInteger)
1446*8975f5c5SAndroid Build Coastguard Worker {
1447*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context->isWebGL());
1448*8975f5c5SAndroid Build Coastguard Worker     // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
1449*8975f5c5SAndroid Build Coastguard Worker     // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
1450*8975f5c5SAndroid Build Coastguard Worker     // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
1451*8975f5c5SAndroid Build Coastguard Worker     // parameter exceeds 255.
1452*8975f5c5SAndroid Build Coastguard Worker     constexpr GLsizei kMaxWebGLStride = 255;
1453*8975f5c5SAndroid Build Coastguard Worker     if (stride > kMaxWebGLStride)
1454*8975f5c5SAndroid Build Coastguard Worker     {
1455*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kStrideExceedsWebGLLimit);
1456*8975f5c5SAndroid Build Coastguard Worker         return false;
1457*8975f5c5SAndroid Build Coastguard Worker     }
1458*8975f5c5SAndroid Build Coastguard Worker 
1459*8975f5c5SAndroid Build Coastguard Worker     // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1460*8975f5c5SAndroid Build Coastguard Worker     // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1461*8975f5c5SAndroid Build Coastguard Worker     // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1462*8975f5c5SAndroid Build Coastguard Worker     // or an INVALID_OPERATION error is generated.
1463*8975f5c5SAndroid Build Coastguard Worker     angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1464*8975f5c5SAndroid Build Coastguard Worker     size_t typeSize              = GetVertexFormatSize(internalType);
1465*8975f5c5SAndroid Build Coastguard Worker 
1466*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isPow2(typeSize) && typeSize > 0);
1467*8975f5c5SAndroid Build Coastguard Worker     size_t sizeMask = (typeSize - 1);
1468*8975f5c5SAndroid Build Coastguard Worker     if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1469*8975f5c5SAndroid Build Coastguard Worker     {
1470*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
1471*8975f5c5SAndroid Build Coastguard Worker         return false;
1472*8975f5c5SAndroid Build Coastguard Worker     }
1473*8975f5c5SAndroid Build Coastguard Worker 
1474*8975f5c5SAndroid Build Coastguard Worker     if ((stride & sizeMask) != 0)
1475*8975f5c5SAndroid Build Coastguard Worker     {
1476*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
1477*8975f5c5SAndroid Build Coastguard Worker         return false;
1478*8975f5c5SAndroid Build Coastguard Worker     }
1479*8975f5c5SAndroid Build Coastguard Worker 
1480*8975f5c5SAndroid Build Coastguard Worker     return true;
1481*8975f5c5SAndroid Build Coastguard Worker }
1482*8975f5c5SAndroid Build Coastguard Worker 
GetValidProgramNoResolve(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID id)1483*8975f5c5SAndroid Build Coastguard Worker Program *GetValidProgramNoResolve(const Context *context,
1484*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
1485*8975f5c5SAndroid Build Coastguard Worker                                   ShaderProgramID id)
1486*8975f5c5SAndroid Build Coastguard Worker {
1487*8975f5c5SAndroid Build Coastguard Worker     // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1488*8975f5c5SAndroid Build Coastguard Worker     // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1489*8975f5c5SAndroid Build Coastguard Worker     // or program object and INVALID_OPERATION if the provided name identifies an object
1490*8975f5c5SAndroid Build Coastguard Worker     // that is not the expected type."
1491*8975f5c5SAndroid Build Coastguard Worker 
1492*8975f5c5SAndroid Build Coastguard Worker     Program *validProgram = context->getProgramNoResolveLink(id);
1493*8975f5c5SAndroid Build Coastguard Worker 
1494*8975f5c5SAndroid Build Coastguard Worker     if (!validProgram)
1495*8975f5c5SAndroid Build Coastguard Worker     {
1496*8975f5c5SAndroid Build Coastguard Worker         if (context->getShaderNoResolveCompile(id))
1497*8975f5c5SAndroid Build Coastguard Worker         {
1498*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
1499*8975f5c5SAndroid Build Coastguard Worker         }
1500*8975f5c5SAndroid Build Coastguard Worker         else
1501*8975f5c5SAndroid Build Coastguard Worker         {
1502*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramName);
1503*8975f5c5SAndroid Build Coastguard Worker         }
1504*8975f5c5SAndroid Build Coastguard Worker     }
1505*8975f5c5SAndroid Build Coastguard Worker 
1506*8975f5c5SAndroid Build Coastguard Worker     return validProgram;
1507*8975f5c5SAndroid Build Coastguard Worker }
1508*8975f5c5SAndroid Build Coastguard Worker 
GetValidProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID id)1509*8975f5c5SAndroid Build Coastguard Worker Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id)
1510*8975f5c5SAndroid Build Coastguard Worker {
1511*8975f5c5SAndroid Build Coastguard Worker     Program *program = GetValidProgramNoResolve(context, entryPoint, id);
1512*8975f5c5SAndroid Build Coastguard Worker     if (program)
1513*8975f5c5SAndroid Build Coastguard Worker     {
1514*8975f5c5SAndroid Build Coastguard Worker         program->resolveLink(context);
1515*8975f5c5SAndroid Build Coastguard Worker     }
1516*8975f5c5SAndroid Build Coastguard Worker     return program;
1517*8975f5c5SAndroid Build Coastguard Worker }
1518*8975f5c5SAndroid Build Coastguard Worker 
GetValidShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID id)1519*8975f5c5SAndroid Build Coastguard Worker Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id)
1520*8975f5c5SAndroid Build Coastguard Worker {
1521*8975f5c5SAndroid Build Coastguard Worker     // See ValidProgram for spec details.
1522*8975f5c5SAndroid Build Coastguard Worker 
1523*8975f5c5SAndroid Build Coastguard Worker     Shader *validShader = context->getShaderNoResolveCompile(id);
1524*8975f5c5SAndroid Build Coastguard Worker 
1525*8975f5c5SAndroid Build Coastguard Worker     if (!validShader)
1526*8975f5c5SAndroid Build Coastguard Worker     {
1527*8975f5c5SAndroid Build Coastguard Worker         if (context->getProgramNoResolveLink(id))
1528*8975f5c5SAndroid Build Coastguard Worker         {
1529*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedShaderName);
1530*8975f5c5SAndroid Build Coastguard Worker         }
1531*8975f5c5SAndroid Build Coastguard Worker         else
1532*8975f5c5SAndroid Build Coastguard Worker         {
1533*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidShaderName);
1534*8975f5c5SAndroid Build Coastguard Worker         }
1535*8975f5c5SAndroid Build Coastguard Worker     }
1536*8975f5c5SAndroid Build Coastguard Worker 
1537*8975f5c5SAndroid Build Coastguard Worker     return validShader;
1538*8975f5c5SAndroid Build Coastguard Worker }
1539*8975f5c5SAndroid Build Coastguard Worker 
ValidateAttachmentTarget(const Context * context,angle::EntryPoint entryPoint,GLenum attachment)1540*8975f5c5SAndroid Build Coastguard Worker bool ValidateAttachmentTarget(const Context *context,
1541*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
1542*8975f5c5SAndroid Build Coastguard Worker                               GLenum attachment)
1543*8975f5c5SAndroid Build Coastguard Worker {
1544*8975f5c5SAndroid Build Coastguard Worker     if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
1545*8975f5c5SAndroid Build Coastguard Worker     {
1546*8975f5c5SAndroid Build Coastguard Worker         if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffersEXT)
1547*8975f5c5SAndroid Build Coastguard Worker         {
1548*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
1549*8975f5c5SAndroid Build Coastguard Worker             return false;
1550*8975f5c5SAndroid Build Coastguard Worker         }
1551*8975f5c5SAndroid Build Coastguard Worker 
1552*8975f5c5SAndroid Build Coastguard Worker         // Color attachment 0 is validated below because it is always valid
1553*8975f5c5SAndroid Build Coastguard Worker         const int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
1554*8975f5c5SAndroid Build Coastguard Worker         if (colorAttachment >= context->getCaps().maxColorAttachments)
1555*8975f5c5SAndroid Build Coastguard Worker         {
1556*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
1557*8975f5c5SAndroid Build Coastguard Worker             return false;
1558*8975f5c5SAndroid Build Coastguard Worker         }
1559*8975f5c5SAndroid Build Coastguard Worker     }
1560*8975f5c5SAndroid Build Coastguard Worker     else
1561*8975f5c5SAndroid Build Coastguard Worker     {
1562*8975f5c5SAndroid Build Coastguard Worker         switch (attachment)
1563*8975f5c5SAndroid Build Coastguard Worker         {
1564*8975f5c5SAndroid Build Coastguard Worker             case GL_COLOR_ATTACHMENT0:
1565*8975f5c5SAndroid Build Coastguard Worker             case GL_DEPTH_ATTACHMENT:
1566*8975f5c5SAndroid Build Coastguard Worker             case GL_STENCIL_ATTACHMENT:
1567*8975f5c5SAndroid Build Coastguard Worker                 break;
1568*8975f5c5SAndroid Build Coastguard Worker 
1569*8975f5c5SAndroid Build Coastguard Worker             case GL_DEPTH_STENCIL_ATTACHMENT:
1570*8975f5c5SAndroid Build Coastguard Worker                 if (!context->isWebGL() && context->getClientMajorVersion() < 3)
1571*8975f5c5SAndroid Build Coastguard Worker                 {
1572*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
1573*8975f5c5SAndroid Build Coastguard Worker                     return false;
1574*8975f5c5SAndroid Build Coastguard Worker                 }
1575*8975f5c5SAndroid Build Coastguard Worker                 break;
1576*8975f5c5SAndroid Build Coastguard Worker 
1577*8975f5c5SAndroid Build Coastguard Worker             default:
1578*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
1579*8975f5c5SAndroid Build Coastguard Worker                 return false;
1580*8975f5c5SAndroid Build Coastguard Worker         }
1581*8975f5c5SAndroid Build Coastguard Worker     }
1582*8975f5c5SAndroid Build Coastguard Worker 
1583*8975f5c5SAndroid Build Coastguard Worker     return true;
1584*8975f5c5SAndroid Build Coastguard Worker }
1585*8975f5c5SAndroid Build Coastguard Worker 
ValidateRenderbufferStorageParametersBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)1586*8975f5c5SAndroid Build Coastguard Worker bool ValidateRenderbufferStorageParametersBase(const Context *context,
1587*8975f5c5SAndroid Build Coastguard Worker                                                angle::EntryPoint entryPoint,
1588*8975f5c5SAndroid Build Coastguard Worker                                                GLenum target,
1589*8975f5c5SAndroid Build Coastguard Worker                                                GLsizei samples,
1590*8975f5c5SAndroid Build Coastguard Worker                                                GLenum internalformat,
1591*8975f5c5SAndroid Build Coastguard Worker                                                GLsizei width,
1592*8975f5c5SAndroid Build Coastguard Worker                                                GLsizei height)
1593*8975f5c5SAndroid Build Coastguard Worker {
1594*8975f5c5SAndroid Build Coastguard Worker     switch (target)
1595*8975f5c5SAndroid Build Coastguard Worker     {
1596*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER:
1597*8975f5c5SAndroid Build Coastguard Worker             break;
1598*8975f5c5SAndroid Build Coastguard Worker         default:
1599*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
1600*8975f5c5SAndroid Build Coastguard Worker             return false;
1601*8975f5c5SAndroid Build Coastguard Worker     }
1602*8975f5c5SAndroid Build Coastguard Worker 
1603*8975f5c5SAndroid Build Coastguard Worker     if (width < 0 || height < 0 || samples < 0)
1604*8975f5c5SAndroid Build Coastguard Worker     {
1605*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
1606*8975f5c5SAndroid Build Coastguard Worker         return false;
1607*8975f5c5SAndroid Build Coastguard Worker     }
1608*8975f5c5SAndroid Build Coastguard Worker 
1609*8975f5c5SAndroid Build Coastguard Worker     // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1610*8975f5c5SAndroid Build Coastguard Worker     GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1611*8975f5c5SAndroid Build Coastguard Worker 
1612*8975f5c5SAndroid Build Coastguard Worker     const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
1613*8975f5c5SAndroid Build Coastguard Worker     if (!formatCaps.renderbuffer)
1614*8975f5c5SAndroid Build Coastguard Worker     {
1615*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
1616*8975f5c5SAndroid Build Coastguard Worker         return false;
1617*8975f5c5SAndroid Build Coastguard Worker     }
1618*8975f5c5SAndroid Build Coastguard Worker 
1619*8975f5c5SAndroid Build Coastguard Worker     // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1620*8975f5c5SAndroid Build Coastguard Worker     // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
1621*8975f5c5SAndroid Build Coastguard Worker     // only sized internal formats.
1622*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
1623*8975f5c5SAndroid Build Coastguard Worker     if (formatInfo.internalFormat == GL_NONE)
1624*8975f5c5SAndroid Build Coastguard Worker     {
1625*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
1626*8975f5c5SAndroid Build Coastguard Worker         return false;
1627*8975f5c5SAndroid Build Coastguard Worker     }
1628*8975f5c5SAndroid Build Coastguard Worker 
1629*8975f5c5SAndroid Build Coastguard Worker     if (std::max(width, height) > context->getCaps().maxRenderbufferSize)
1630*8975f5c5SAndroid Build Coastguard Worker     {
1631*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
1632*8975f5c5SAndroid Build Coastguard Worker         return false;
1633*8975f5c5SAndroid Build Coastguard Worker     }
1634*8975f5c5SAndroid Build Coastguard Worker 
1635*8975f5c5SAndroid Build Coastguard Worker     RenderbufferID id = context->getState().getRenderbufferId();
1636*8975f5c5SAndroid Build Coastguard Worker     if (id.value == 0)
1637*8975f5c5SAndroid Build Coastguard Worker     {
1638*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
1639*8975f5c5SAndroid Build Coastguard Worker         return false;
1640*8975f5c5SAndroid Build Coastguard Worker     }
1641*8975f5c5SAndroid Build Coastguard Worker 
1642*8975f5c5SAndroid Build Coastguard Worker     return true;
1643*8975f5c5SAndroid Build Coastguard Worker }
1644*8975f5c5SAndroid Build Coastguard Worker 
ValidateBlitFramebufferParameters(const Context * context,angle::EntryPoint entryPoint,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)1645*8975f5c5SAndroid Build Coastguard Worker bool ValidateBlitFramebufferParameters(const Context *context,
1646*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
1647*8975f5c5SAndroid Build Coastguard Worker                                        GLint srcX0,
1648*8975f5c5SAndroid Build Coastguard Worker                                        GLint srcY0,
1649*8975f5c5SAndroid Build Coastguard Worker                                        GLint srcX1,
1650*8975f5c5SAndroid Build Coastguard Worker                                        GLint srcY1,
1651*8975f5c5SAndroid Build Coastguard Worker                                        GLint dstX0,
1652*8975f5c5SAndroid Build Coastguard Worker                                        GLint dstY0,
1653*8975f5c5SAndroid Build Coastguard Worker                                        GLint dstX1,
1654*8975f5c5SAndroid Build Coastguard Worker                                        GLint dstY1,
1655*8975f5c5SAndroid Build Coastguard Worker                                        GLbitfield mask,
1656*8975f5c5SAndroid Build Coastguard Worker                                        GLenum filter)
1657*8975f5c5SAndroid Build Coastguard Worker {
1658*8975f5c5SAndroid Build Coastguard Worker     switch (filter)
1659*8975f5c5SAndroid Build Coastguard Worker     {
1660*8975f5c5SAndroid Build Coastguard Worker         case GL_NEAREST:
1661*8975f5c5SAndroid Build Coastguard Worker             break;
1662*8975f5c5SAndroid Build Coastguard Worker         case GL_LINEAR:
1663*8975f5c5SAndroid Build Coastguard Worker             break;
1664*8975f5c5SAndroid Build Coastguard Worker         default:
1665*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kBlitInvalidFilter);
1666*8975f5c5SAndroid Build Coastguard Worker             return false;
1667*8975f5c5SAndroid Build Coastguard Worker     }
1668*8975f5c5SAndroid Build Coastguard Worker 
1669*8975f5c5SAndroid Build Coastguard Worker     if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1670*8975f5c5SAndroid Build Coastguard Worker     {
1671*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBlitInvalidMask);
1672*8975f5c5SAndroid Build Coastguard Worker         return false;
1673*8975f5c5SAndroid Build Coastguard Worker     }
1674*8975f5c5SAndroid Build Coastguard Worker 
1675*8975f5c5SAndroid Build Coastguard Worker     // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1676*8975f5c5SAndroid Build Coastguard Worker     // color buffer, leaving only nearest being unfiltered from above
1677*8975f5c5SAndroid Build Coastguard Worker     if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1678*8975f5c5SAndroid Build Coastguard Worker     {
1679*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
1680*8975f5c5SAndroid Build Coastguard Worker         return false;
1681*8975f5c5SAndroid Build Coastguard Worker     }
1682*8975f5c5SAndroid Build Coastguard Worker 
1683*8975f5c5SAndroid Build Coastguard Worker     const auto &glState          = context->getState();
1684*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1685*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
1686*8975f5c5SAndroid Build Coastguard Worker 
1687*8975f5c5SAndroid Build Coastguard Worker     if (!readFramebuffer || !drawFramebuffer)
1688*8975f5c5SAndroid Build Coastguard Worker     {
1689*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFramebufferMissing);
1690*8975f5c5SAndroid Build Coastguard Worker         return false;
1691*8975f5c5SAndroid Build Coastguard Worker     }
1692*8975f5c5SAndroid Build Coastguard Worker 
1693*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
1694*8975f5c5SAndroid Build Coastguard Worker     {
1695*8975f5c5SAndroid Build Coastguard Worker         return false;
1696*8975f5c5SAndroid Build Coastguard Worker     }
1697*8975f5c5SAndroid Build Coastguard Worker 
1698*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateFramebufferComplete(context, entryPoint, drawFramebuffer))
1699*8975f5c5SAndroid Build Coastguard Worker     {
1700*8975f5c5SAndroid Build Coastguard Worker         return false;
1701*8975f5c5SAndroid Build Coastguard Worker     }
1702*8975f5c5SAndroid Build Coastguard Worker 
1703*8975f5c5SAndroid Build Coastguard Worker     // The QCOM_framebuffer_foveated spec:
1704*8975f5c5SAndroid Build Coastguard Worker     if (drawFramebuffer->isFoveationEnabled())
1705*8975f5c5SAndroid Build Coastguard Worker     {
1706*8975f5c5SAndroid Build Coastguard Worker         // INVALID_OPERATION is generated by any API call which causes a framebuffer
1707*8975f5c5SAndroid Build Coastguard Worker         // attachment to be written to if the framebuffer attachments have changed for
1708*8975f5c5SAndroid Build Coastguard Worker         // a foveated fbo.
1709*8975f5c5SAndroid Build Coastguard Worker         if (drawFramebuffer->hasAnyAttachmentChanged())
1710*8975f5c5SAndroid Build Coastguard Worker         {
1711*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationAttachmentChanged);
1712*8975f5c5SAndroid Build Coastguard Worker             return false;
1713*8975f5c5SAndroid Build Coastguard Worker         }
1714*8975f5c5SAndroid Build Coastguard Worker     }
1715*8975f5c5SAndroid Build Coastguard Worker 
1716*8975f5c5SAndroid Build Coastguard Worker     // EXT_YUV_target disallows blitting to or from a YUV framebuffer
1717*8975f5c5SAndroid Build Coastguard Worker     if ((mask & GL_COLOR_BUFFER_BIT) != 0 &&
1718*8975f5c5SAndroid Build Coastguard Worker         (readFramebuffer->hasYUVAttachment() || drawFramebuffer->hasYUVAttachment()))
1719*8975f5c5SAndroid Build Coastguard Worker     {
1720*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitYUVFramebuffer);
1721*8975f5c5SAndroid Build Coastguard Worker         return false;
1722*8975f5c5SAndroid Build Coastguard Worker     }
1723*8975f5c5SAndroid Build Coastguard Worker 
1724*8975f5c5SAndroid Build Coastguard Worker     // The draw and read framebuffers can only match if:
1725*8975f5c5SAndroid Build Coastguard Worker     // - They are the default framebuffer AND
1726*8975f5c5SAndroid Build Coastguard Worker     // - The read/draw surfaces are different
1727*8975f5c5SAndroid Build Coastguard Worker     if ((readFramebuffer->id() == drawFramebuffer->id()) &&
1728*8975f5c5SAndroid Build Coastguard Worker         ((drawFramebuffer->id() != Framebuffer::kDefaultDrawFramebufferHandle) ||
1729*8975f5c5SAndroid Build Coastguard Worker          (context->getCurrentDrawSurface() == context->getCurrentReadSurface())))
1730*8975f5c5SAndroid Build Coastguard Worker     {
1731*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitFeedbackLoop);
1732*8975f5c5SAndroid Build Coastguard Worker         return false;
1733*8975f5c5SAndroid Build Coastguard Worker     }
1734*8975f5c5SAndroid Build Coastguard Worker 
1735*8975f5c5SAndroid Build Coastguard Worker     // Not allow blitting to MS buffers, therefore if renderToTextureSamples exist,
1736*8975f5c5SAndroid Build Coastguard Worker     // consider it MS. checkReadBufferResourceSamples = false
1737*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateFramebufferNotMultisampled(context, entryPoint, drawFramebuffer, false))
1738*8975f5c5SAndroid Build Coastguard Worker     {
1739*8975f5c5SAndroid Build Coastguard Worker         return false;
1740*8975f5c5SAndroid Build Coastguard Worker     }
1741*8975f5c5SAndroid Build Coastguard Worker 
1742*8975f5c5SAndroid Build Coastguard Worker     // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1743*8975f5c5SAndroid Build Coastguard Worker     // always run it in order to avoid triggering driver bugs.
1744*8975f5c5SAndroid Build Coastguard Worker     if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1745*8975f5c5SAndroid Build Coastguard Worker         DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
1746*8975f5c5SAndroid Build Coastguard Worker     {
1747*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
1748*8975f5c5SAndroid Build Coastguard Worker         return false;
1749*8975f5c5SAndroid Build Coastguard Worker     }
1750*8975f5c5SAndroid Build Coastguard Worker 
1751*8975f5c5SAndroid Build Coastguard Worker     bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1752*8975f5c5SAndroid Build Coastguard Worker 
1753*8975f5c5SAndroid Build Coastguard Worker     if (mask & GL_COLOR_BUFFER_BIT)
1754*8975f5c5SAndroid Build Coastguard Worker     {
1755*8975f5c5SAndroid Build Coastguard Worker         const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorAttachment();
1756*8975f5c5SAndroid Build Coastguard Worker         const Extensions &extensions                 = context->getExtensions();
1757*8975f5c5SAndroid Build Coastguard Worker 
1758*8975f5c5SAndroid Build Coastguard Worker         if (readColorBuffer)
1759*8975f5c5SAndroid Build Coastguard Worker         {
1760*8975f5c5SAndroid Build Coastguard Worker             const Format &readFormat = readColorBuffer->getFormat();
1761*8975f5c5SAndroid Build Coastguard Worker 
1762*8975f5c5SAndroid Build Coastguard Worker             for (size_t drawbufferIdx = 0;
1763*8975f5c5SAndroid Build Coastguard Worker                  drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
1764*8975f5c5SAndroid Build Coastguard Worker             {
1765*8975f5c5SAndroid Build Coastguard Worker                 const FramebufferAttachment *attachment =
1766*8975f5c5SAndroid Build Coastguard Worker                     drawFramebuffer->getDrawBuffer(drawbufferIdx);
1767*8975f5c5SAndroid Build Coastguard Worker                 if (attachment)
1768*8975f5c5SAndroid Build Coastguard Worker                 {
1769*8975f5c5SAndroid Build Coastguard Worker                     const Format &drawFormat = attachment->getFormat();
1770*8975f5c5SAndroid Build Coastguard Worker 
1771*8975f5c5SAndroid Build Coastguard Worker                     // The GL ES 3.0.2 spec (pg 193) states that:
1772*8975f5c5SAndroid Build Coastguard Worker                     // 1) If the read buffer is fixed point format, the draw buffer must be as well
1773*8975f5c5SAndroid Build Coastguard Worker                     // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1774*8975f5c5SAndroid Build Coastguard Worker                     // as well
1775*8975f5c5SAndroid Build Coastguard Worker                     // 3) If the read buffer is a signed integer format, the draw buffer must be as
1776*8975f5c5SAndroid Build Coastguard Worker                     // well
1777*8975f5c5SAndroid Build Coastguard Worker                     // Changes with EXT_color_buffer_float:
1778*8975f5c5SAndroid Build Coastguard Worker                     // Case 1) is changed to fixed point OR floating point
1779*8975f5c5SAndroid Build Coastguard Worker                     GLenum readComponentType = readFormat.info->componentType;
1780*8975f5c5SAndroid Build Coastguard Worker                     GLenum drawComponentType = drawFormat.info->componentType;
1781*8975f5c5SAndroid Build Coastguard Worker                     bool readFixedPoint      = (readComponentType == GL_UNSIGNED_NORMALIZED ||
1782*8975f5c5SAndroid Build Coastguard Worker                                            readComponentType == GL_SIGNED_NORMALIZED);
1783*8975f5c5SAndroid Build Coastguard Worker                     bool drawFixedPoint      = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
1784*8975f5c5SAndroid Build Coastguard Worker                                            drawComponentType == GL_SIGNED_NORMALIZED);
1785*8975f5c5SAndroid Build Coastguard Worker 
1786*8975f5c5SAndroid Build Coastguard Worker                     if (extensions.colorBufferFloatEXT)
1787*8975f5c5SAndroid Build Coastguard Worker                     {
1788*8975f5c5SAndroid Build Coastguard Worker                         bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1789*8975f5c5SAndroid Build Coastguard Worker                         bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1790*8975f5c5SAndroid Build Coastguard Worker 
1791*8975f5c5SAndroid Build Coastguard Worker                         if (readFixedOrFloat != drawFixedOrFloat)
1792*8975f5c5SAndroid Build Coastguard Worker                         {
1793*8975f5c5SAndroid Build Coastguard Worker                             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1794*8975f5c5SAndroid Build Coastguard Worker                                                    kBlitTypeMismatchFixedOrFloat);
1795*8975f5c5SAndroid Build Coastguard Worker                             return false;
1796*8975f5c5SAndroid Build Coastguard Worker                         }
1797*8975f5c5SAndroid Build Coastguard Worker                     }
1798*8975f5c5SAndroid Build Coastguard Worker                     else if (readFixedPoint != drawFixedPoint)
1799*8975f5c5SAndroid Build Coastguard Worker                     {
1800*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitTypeMismatchFixedPoint);
1801*8975f5c5SAndroid Build Coastguard Worker                         return false;
1802*8975f5c5SAndroid Build Coastguard Worker                     }
1803*8975f5c5SAndroid Build Coastguard Worker 
1804*8975f5c5SAndroid Build Coastguard Worker                     if (readComponentType == GL_UNSIGNED_INT &&
1805*8975f5c5SAndroid Build Coastguard Worker                         drawComponentType != GL_UNSIGNED_INT)
1806*8975f5c5SAndroid Build Coastguard Worker                     {
1807*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1808*8975f5c5SAndroid Build Coastguard Worker                                                kBlitTypeMismatchUnsignedInteger);
1809*8975f5c5SAndroid Build Coastguard Worker                         return false;
1810*8975f5c5SAndroid Build Coastguard Worker                     }
1811*8975f5c5SAndroid Build Coastguard Worker 
1812*8975f5c5SAndroid Build Coastguard Worker                     if (readComponentType == GL_INT && drawComponentType != GL_INT)
1813*8975f5c5SAndroid Build Coastguard Worker                     {
1814*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1815*8975f5c5SAndroid Build Coastguard Worker                                                kBlitTypeMismatchSignedInteger);
1816*8975f5c5SAndroid Build Coastguard Worker                         return false;
1817*8975f5c5SAndroid Build Coastguard Worker                     }
1818*8975f5c5SAndroid Build Coastguard Worker 
1819*8975f5c5SAndroid Build Coastguard Worker                     if (readColorBuffer->getResourceSamples() > 0 &&
1820*8975f5c5SAndroid Build Coastguard Worker                         (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
1821*8975f5c5SAndroid Build Coastguard Worker                     {
1822*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1823*8975f5c5SAndroid Build Coastguard Worker                                                kBlitMultisampledFormatOrBoundsMismatch);
1824*8975f5c5SAndroid Build Coastguard Worker                         return false;
1825*8975f5c5SAndroid Build Coastguard Worker                     }
1826*8975f5c5SAndroid Build Coastguard Worker 
1827*8975f5c5SAndroid Build Coastguard Worker                     if (context->isWebGL() && *readColorBuffer == *attachment)
1828*8975f5c5SAndroid Build Coastguard Worker                     {
1829*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitSameImageColor);
1830*8975f5c5SAndroid Build Coastguard Worker                         return false;
1831*8975f5c5SAndroid Build Coastguard Worker                     }
1832*8975f5c5SAndroid Build Coastguard Worker                 }
1833*8975f5c5SAndroid Build Coastguard Worker             }
1834*8975f5c5SAndroid Build Coastguard Worker 
1835*8975f5c5SAndroid Build Coastguard Worker             if (readFormat.info->isInt() && filter == GL_LINEAR)
1836*8975f5c5SAndroid Build Coastguard Worker             {
1837*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitIntegerWithLinearFilter);
1838*8975f5c5SAndroid Build Coastguard Worker                 return false;
1839*8975f5c5SAndroid Build Coastguard Worker             }
1840*8975f5c5SAndroid Build Coastguard Worker         }
1841*8975f5c5SAndroid Build Coastguard Worker         // In OpenGL ES, blits to/from missing attachments are silently ignored.  In WebGL 2.0, this
1842*8975f5c5SAndroid Build Coastguard Worker         // is defined to be an error.
1843*8975f5c5SAndroid Build Coastguard Worker         else if (context->isWebGL() && drawFramebuffer->hasEnabledDrawBuffer())
1844*8975f5c5SAndroid Build Coastguard Worker         {
1845*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitMissingColor);
1846*8975f5c5SAndroid Build Coastguard Worker             return false;
1847*8975f5c5SAndroid Build Coastguard Worker         }
1848*8975f5c5SAndroid Build Coastguard Worker     }
1849*8975f5c5SAndroid Build Coastguard Worker 
1850*8975f5c5SAndroid Build Coastguard Worker     GLenum masks[]       = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
1851*8975f5c5SAndroid Build Coastguard Worker     GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1852*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 2; i++)
1853*8975f5c5SAndroid Build Coastguard Worker     {
1854*8975f5c5SAndroid Build Coastguard Worker         if (mask & masks[i])
1855*8975f5c5SAndroid Build Coastguard Worker         {
1856*8975f5c5SAndroid Build Coastguard Worker             const FramebufferAttachment *readBuffer =
1857*8975f5c5SAndroid Build Coastguard Worker                 readFramebuffer->getAttachment(context, attachments[i]);
1858*8975f5c5SAndroid Build Coastguard Worker             const FramebufferAttachment *drawBuffer =
1859*8975f5c5SAndroid Build Coastguard Worker                 drawFramebuffer->getAttachment(context, attachments[i]);
1860*8975f5c5SAndroid Build Coastguard Worker 
1861*8975f5c5SAndroid Build Coastguard Worker             if (readBuffer && drawBuffer)
1862*8975f5c5SAndroid Build Coastguard Worker             {
1863*8975f5c5SAndroid Build Coastguard Worker                 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
1864*8975f5c5SAndroid Build Coastguard Worker                 {
1865*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitDepthOrStencilFormatMismatch);
1866*8975f5c5SAndroid Build Coastguard Worker                     return false;
1867*8975f5c5SAndroid Build Coastguard Worker                 }
1868*8975f5c5SAndroid Build Coastguard Worker 
1869*8975f5c5SAndroid Build Coastguard Worker                 if (readBuffer->getResourceSamples() > 0 && !sameBounds)
1870*8975f5c5SAndroid Build Coastguard Worker                 {
1871*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitMultisampledBoundsMismatch);
1872*8975f5c5SAndroid Build Coastguard Worker                     return false;
1873*8975f5c5SAndroid Build Coastguard Worker                 }
1874*8975f5c5SAndroid Build Coastguard Worker 
1875*8975f5c5SAndroid Build Coastguard Worker                 if (context->isWebGL() && *readBuffer == *drawBuffer)
1876*8975f5c5SAndroid Build Coastguard Worker                 {
1877*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitSameImageDepthOrStencil);
1878*8975f5c5SAndroid Build Coastguard Worker                     return false;
1879*8975f5c5SAndroid Build Coastguard Worker                 }
1880*8975f5c5SAndroid Build Coastguard Worker             }
1881*8975f5c5SAndroid Build Coastguard Worker             // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1882*8975f5c5SAndroid Build Coastguard Worker             else if (context->isWebGL() && drawBuffer)
1883*8975f5c5SAndroid Build Coastguard Worker             {
1884*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitMissingDepthOrStencil);
1885*8975f5c5SAndroid Build Coastguard Worker                 return false;
1886*8975f5c5SAndroid Build Coastguard Worker             }
1887*8975f5c5SAndroid Build Coastguard Worker         }
1888*8975f5c5SAndroid Build Coastguard Worker     }
1889*8975f5c5SAndroid Build Coastguard Worker 
1890*8975f5c5SAndroid Build Coastguard Worker     // OVR_multiview2:
1891*8975f5c5SAndroid Build Coastguard Worker     // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
1892*8975f5c5SAndroid Build Coastguard Worker     // current draw framebuffer isMultiview() or the number of
1893*8975f5c5SAndroid Build Coastguard Worker     // views in the current read framebuffer is more than one.
1894*8975f5c5SAndroid Build Coastguard Worker     if (readFramebuffer->readDisallowedByMultiview())
1895*8975f5c5SAndroid Build Coastguard Worker     {
1896*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
1897*8975f5c5SAndroid Build Coastguard Worker         return false;
1898*8975f5c5SAndroid Build Coastguard Worker     }
1899*8975f5c5SAndroid Build Coastguard Worker     if (drawFramebuffer->isMultiview())
1900*8975f5c5SAndroid Build Coastguard Worker     {
1901*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
1902*8975f5c5SAndroid Build Coastguard Worker         return false;
1903*8975f5c5SAndroid Build Coastguard Worker     }
1904*8975f5c5SAndroid Build Coastguard Worker 
1905*8975f5c5SAndroid Build Coastguard Worker     return true;
1906*8975f5c5SAndroid Build Coastguard Worker }
1907*8975f5c5SAndroid Build Coastguard Worker 
ValidateBindFramebufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,FramebufferID framebuffer)1908*8975f5c5SAndroid Build Coastguard Worker bool ValidateBindFramebufferBase(const Context *context,
1909*8975f5c5SAndroid Build Coastguard Worker                                  angle::EntryPoint entryPoint,
1910*8975f5c5SAndroid Build Coastguard Worker                                  GLenum target,
1911*8975f5c5SAndroid Build Coastguard Worker                                  FramebufferID framebuffer)
1912*8975f5c5SAndroid Build Coastguard Worker {
1913*8975f5c5SAndroid Build Coastguard Worker     if (!ValidFramebufferTarget(context, target))
1914*8975f5c5SAndroid Build Coastguard Worker     {
1915*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1916*8975f5c5SAndroid Build Coastguard Worker         return false;
1917*8975f5c5SAndroid Build Coastguard Worker     }
1918*8975f5c5SAndroid Build Coastguard Worker 
1919*8975f5c5SAndroid Build Coastguard Worker     if (!context->getState().isBindGeneratesResourceEnabled() &&
1920*8975f5c5SAndroid Build Coastguard Worker         !context->isFramebufferGenerated(framebuffer))
1921*8975f5c5SAndroid Build Coastguard Worker     {
1922*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1923*8975f5c5SAndroid Build Coastguard Worker         return false;
1924*8975f5c5SAndroid Build Coastguard Worker     }
1925*8975f5c5SAndroid Build Coastguard Worker 
1926*8975f5c5SAndroid Build Coastguard Worker     return true;
1927*8975f5c5SAndroid Build Coastguard Worker }
1928*8975f5c5SAndroid Build Coastguard Worker 
ValidateBindRenderbufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,RenderbufferID renderbuffer)1929*8975f5c5SAndroid Build Coastguard Worker bool ValidateBindRenderbufferBase(const Context *context,
1930*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
1931*8975f5c5SAndroid Build Coastguard Worker                                   GLenum target,
1932*8975f5c5SAndroid Build Coastguard Worker                                   RenderbufferID renderbuffer)
1933*8975f5c5SAndroid Build Coastguard Worker {
1934*8975f5c5SAndroid Build Coastguard Worker     if (target != GL_RENDERBUFFER)
1935*8975f5c5SAndroid Build Coastguard Worker     {
1936*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
1937*8975f5c5SAndroid Build Coastguard Worker         return false;
1938*8975f5c5SAndroid Build Coastguard Worker     }
1939*8975f5c5SAndroid Build Coastguard Worker 
1940*8975f5c5SAndroid Build Coastguard Worker     if (!context->getState().isBindGeneratesResourceEnabled() &&
1941*8975f5c5SAndroid Build Coastguard Worker         !context->isRenderbufferGenerated(renderbuffer))
1942*8975f5c5SAndroid Build Coastguard Worker     {
1943*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1944*8975f5c5SAndroid Build Coastguard Worker         return false;
1945*8975f5c5SAndroid Build Coastguard Worker     }
1946*8975f5c5SAndroid Build Coastguard Worker 
1947*8975f5c5SAndroid Build Coastguard Worker     return true;
1948*8975f5c5SAndroid Build Coastguard Worker }
1949*8975f5c5SAndroid Build Coastguard Worker 
ValidateFramebufferParameteriBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLint param)1950*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferParameteriBase(const Context *context,
1951*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
1952*8975f5c5SAndroid Build Coastguard Worker                                        GLenum target,
1953*8975f5c5SAndroid Build Coastguard Worker                                        GLenum pname,
1954*8975f5c5SAndroid Build Coastguard Worker                                        GLint param)
1955*8975f5c5SAndroid Build Coastguard Worker {
1956*8975f5c5SAndroid Build Coastguard Worker     if (!ValidFramebufferTarget(context, target))
1957*8975f5c5SAndroid Build Coastguard Worker     {
1958*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1959*8975f5c5SAndroid Build Coastguard Worker         return false;
1960*8975f5c5SAndroid Build Coastguard Worker     }
1961*8975f5c5SAndroid Build Coastguard Worker 
1962*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
1963*8975f5c5SAndroid Build Coastguard Worker     {
1964*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1965*8975f5c5SAndroid Build Coastguard Worker         {
1966*8975f5c5SAndroid Build Coastguard Worker             GLint maxWidth = context->getCaps().maxFramebufferWidth;
1967*8975f5c5SAndroid Build Coastguard Worker             if (param < 0 || param > maxWidth)
1968*8975f5c5SAndroid Build Coastguard Worker             {
1969*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsFramebufferWidth);
1970*8975f5c5SAndroid Build Coastguard Worker                 return false;
1971*8975f5c5SAndroid Build Coastguard Worker             }
1972*8975f5c5SAndroid Build Coastguard Worker             break;
1973*8975f5c5SAndroid Build Coastguard Worker         }
1974*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1975*8975f5c5SAndroid Build Coastguard Worker         {
1976*8975f5c5SAndroid Build Coastguard Worker             GLint maxHeight = context->getCaps().maxFramebufferHeight;
1977*8975f5c5SAndroid Build Coastguard Worker             if (param < 0 || param > maxHeight)
1978*8975f5c5SAndroid Build Coastguard Worker             {
1979*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsFramebufferHeight);
1980*8975f5c5SAndroid Build Coastguard Worker                 return false;
1981*8975f5c5SAndroid Build Coastguard Worker             }
1982*8975f5c5SAndroid Build Coastguard Worker             break;
1983*8975f5c5SAndroid Build Coastguard Worker         }
1984*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1985*8975f5c5SAndroid Build Coastguard Worker         {
1986*8975f5c5SAndroid Build Coastguard Worker             GLint maxSamples = context->getCaps().maxFramebufferSamples;
1987*8975f5c5SAndroid Build Coastguard Worker             if (param < 0 || param > maxSamples)
1988*8975f5c5SAndroid Build Coastguard Worker             {
1989*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsFramebufferSamples);
1990*8975f5c5SAndroid Build Coastguard Worker                 return false;
1991*8975f5c5SAndroid Build Coastguard Worker             }
1992*8975f5c5SAndroid Build Coastguard Worker             break;
1993*8975f5c5SAndroid Build Coastguard Worker         }
1994*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1995*8975f5c5SAndroid Build Coastguard Worker         {
1996*8975f5c5SAndroid Build Coastguard Worker             break;
1997*8975f5c5SAndroid Build Coastguard Worker         }
1998*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1999*8975f5c5SAndroid Build Coastguard Worker         {
2000*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().geometryShaderAny() &&
2001*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
2002*8975f5c5SAndroid Build Coastguard Worker             {
2003*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
2004*8975f5c5SAndroid Build Coastguard Worker                 return false;
2005*8975f5c5SAndroid Build Coastguard Worker             }
2006*8975f5c5SAndroid Build Coastguard Worker             GLint maxLayers = context->getCaps().maxFramebufferLayers;
2007*8975f5c5SAndroid Build Coastguard Worker             if (param < 0 || param > maxLayers)
2008*8975f5c5SAndroid Build Coastguard Worker             {
2009*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferLayer);
2010*8975f5c5SAndroid Build Coastguard Worker                 return false;
2011*8975f5c5SAndroid Build Coastguard Worker             }
2012*8975f5c5SAndroid Build Coastguard Worker             break;
2013*8975f5c5SAndroid Build Coastguard Worker         }
2014*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_FLIP_Y_MESA:
2015*8975f5c5SAndroid Build Coastguard Worker         {
2016*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().framebufferFlipYMESA)
2017*8975f5c5SAndroid Build Coastguard Worker             {
2018*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2019*8975f5c5SAndroid Build Coastguard Worker                 return false;
2020*8975f5c5SAndroid Build Coastguard Worker             }
2021*8975f5c5SAndroid Build Coastguard Worker             break;
2022*8975f5c5SAndroid Build Coastguard Worker         }
2023*8975f5c5SAndroid Build Coastguard Worker         default:
2024*8975f5c5SAndroid Build Coastguard Worker         {
2025*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2026*8975f5c5SAndroid Build Coastguard Worker             return false;
2027*8975f5c5SAndroid Build Coastguard Worker         }
2028*8975f5c5SAndroid Build Coastguard Worker     }
2029*8975f5c5SAndroid Build Coastguard Worker 
2030*8975f5c5SAndroid Build Coastguard Worker     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
2031*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebuffer);
2032*8975f5c5SAndroid Build Coastguard Worker     if (framebuffer->isDefault())
2033*8975f5c5SAndroid Build Coastguard Worker     {
2034*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebuffer);
2035*8975f5c5SAndroid Build Coastguard Worker         return false;
2036*8975f5c5SAndroid Build Coastguard Worker     }
2037*8975f5c5SAndroid Build Coastguard Worker     return true;
2038*8975f5c5SAndroid Build Coastguard Worker }
2039*8975f5c5SAndroid Build Coastguard Worker 
ValidateFramebufferRenderbufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum renderbuffertarget,RenderbufferID renderbuffer)2040*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferRenderbufferBase(const Context *context,
2041*8975f5c5SAndroid Build Coastguard Worker                                          angle::EntryPoint entryPoint,
2042*8975f5c5SAndroid Build Coastguard Worker                                          GLenum target,
2043*8975f5c5SAndroid Build Coastguard Worker                                          GLenum attachment,
2044*8975f5c5SAndroid Build Coastguard Worker                                          GLenum renderbuffertarget,
2045*8975f5c5SAndroid Build Coastguard Worker                                          RenderbufferID renderbuffer)
2046*8975f5c5SAndroid Build Coastguard Worker {
2047*8975f5c5SAndroid Build Coastguard Worker     if (!ValidFramebufferTarget(context, target))
2048*8975f5c5SAndroid Build Coastguard Worker     {
2049*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
2050*8975f5c5SAndroid Build Coastguard Worker         return false;
2051*8975f5c5SAndroid Build Coastguard Worker     }
2052*8975f5c5SAndroid Build Coastguard Worker 
2053*8975f5c5SAndroid Build Coastguard Worker     if (renderbuffertarget != GL_RENDERBUFFER)
2054*8975f5c5SAndroid Build Coastguard Worker     {
2055*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
2056*8975f5c5SAndroid Build Coastguard Worker         return false;
2057*8975f5c5SAndroid Build Coastguard Worker     }
2058*8975f5c5SAndroid Build Coastguard Worker 
2059*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
2060*8975f5c5SAndroid Build Coastguard Worker 
2061*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebuffer);
2062*8975f5c5SAndroid Build Coastguard Worker     if (framebuffer->isDefault())
2063*8975f5c5SAndroid Build Coastguard Worker     {
2064*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
2065*8975f5c5SAndroid Build Coastguard Worker         return false;
2066*8975f5c5SAndroid Build Coastguard Worker     }
2067*8975f5c5SAndroid Build Coastguard Worker 
2068*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateAttachmentTarget(context, entryPoint, attachment))
2069*8975f5c5SAndroid Build Coastguard Worker     {
2070*8975f5c5SAndroid Build Coastguard Worker         return false;
2071*8975f5c5SAndroid Build Coastguard Worker     }
2072*8975f5c5SAndroid Build Coastguard Worker 
2073*8975f5c5SAndroid Build Coastguard Worker     // [OpenGL ES 2.0.25] Section 4.4.3 page 112
2074*8975f5c5SAndroid Build Coastguard Worker     // [OpenGL ES 3.0.2] Section 4.4.2 page 201
2075*8975f5c5SAndroid Build Coastguard Worker     // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
2076*8975f5c5SAndroid Build Coastguard Worker     // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
2077*8975f5c5SAndroid Build Coastguard Worker     if (renderbuffer.value != 0)
2078*8975f5c5SAndroid Build Coastguard Worker     {
2079*8975f5c5SAndroid Build Coastguard Worker         if (!context->getRenderbuffer(renderbuffer))
2080*8975f5c5SAndroid Build Coastguard Worker         {
2081*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
2082*8975f5c5SAndroid Build Coastguard Worker             return false;
2083*8975f5c5SAndroid Build Coastguard Worker         }
2084*8975f5c5SAndroid Build Coastguard Worker     }
2085*8975f5c5SAndroid Build Coastguard Worker 
2086*8975f5c5SAndroid Build Coastguard Worker     return true;
2087*8975f5c5SAndroid Build Coastguard Worker }
2088*8975f5c5SAndroid Build Coastguard Worker 
ValidateFramebufferTextureBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2089*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferTextureBase(const Context *context,
2090*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
2091*8975f5c5SAndroid Build Coastguard Worker                                     GLenum target,
2092*8975f5c5SAndroid Build Coastguard Worker                                     GLenum attachment,
2093*8975f5c5SAndroid Build Coastguard Worker                                     TextureID texture,
2094*8975f5c5SAndroid Build Coastguard Worker                                     GLint level)
2095*8975f5c5SAndroid Build Coastguard Worker {
2096*8975f5c5SAndroid Build Coastguard Worker     if (!ValidFramebufferTarget(context, target))
2097*8975f5c5SAndroid Build Coastguard Worker     {
2098*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
2099*8975f5c5SAndroid Build Coastguard Worker         return false;
2100*8975f5c5SAndroid Build Coastguard Worker     }
2101*8975f5c5SAndroid Build Coastguard Worker 
2102*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateAttachmentTarget(context, entryPoint, attachment))
2103*8975f5c5SAndroid Build Coastguard Worker     {
2104*8975f5c5SAndroid Build Coastguard Worker         return false;
2105*8975f5c5SAndroid Build Coastguard Worker     }
2106*8975f5c5SAndroid Build Coastguard Worker 
2107*8975f5c5SAndroid Build Coastguard Worker     if (texture.value != 0)
2108*8975f5c5SAndroid Build Coastguard Worker     {
2109*8975f5c5SAndroid Build Coastguard Worker         Texture *tex = context->getTexture(texture);
2110*8975f5c5SAndroid Build Coastguard Worker 
2111*8975f5c5SAndroid Build Coastguard Worker         if (tex == nullptr)
2112*8975f5c5SAndroid Build Coastguard Worker         {
2113*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTexture);
2114*8975f5c5SAndroid Build Coastguard Worker             return false;
2115*8975f5c5SAndroid Build Coastguard Worker         }
2116*8975f5c5SAndroid Build Coastguard Worker 
2117*8975f5c5SAndroid Build Coastguard Worker         if (level < 0)
2118*8975f5c5SAndroid Build Coastguard Worker         {
2119*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
2120*8975f5c5SAndroid Build Coastguard Worker             return false;
2121*8975f5c5SAndroid Build Coastguard Worker         }
2122*8975f5c5SAndroid Build Coastguard Worker 
2123*8975f5c5SAndroid Build Coastguard Worker         // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2124*8975f5c5SAndroid Build Coastguard Worker         // An INVALID_VALUE error is generated if texture is not zero and level is
2125*8975f5c5SAndroid Build Coastguard Worker         // not a supported texture level for textarget
2126*8975f5c5SAndroid Build Coastguard Worker 
2127*8975f5c5SAndroid Build Coastguard Worker         // Common criteria for not supported texture levels(other criteria are handled case by case
2128*8975f5c5SAndroid Build Coastguard Worker         // in non base functions): If texture refers to an immutable-format texture, level must be
2129*8975f5c5SAndroid Build Coastguard Worker         // greater than or equal to zero and smaller than the value of TEXTURE_IMMUTABLE_LEVELS for
2130*8975f5c5SAndroid Build Coastguard Worker         // texture.
2131*8975f5c5SAndroid Build Coastguard Worker         if (tex->getImmutableFormat() && context->getClientVersion() >= ES_3_1)
2132*8975f5c5SAndroid Build Coastguard Worker         {
2133*8975f5c5SAndroid Build Coastguard Worker             if (level >= static_cast<GLint>(tex->getImmutableLevels()))
2134*8975f5c5SAndroid Build Coastguard Worker             {
2135*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
2136*8975f5c5SAndroid Build Coastguard Worker                 return false;
2137*8975f5c5SAndroid Build Coastguard Worker             }
2138*8975f5c5SAndroid Build Coastguard Worker         }
2139*8975f5c5SAndroid Build Coastguard Worker 
2140*8975f5c5SAndroid Build Coastguard Worker         // GLES spec 3.2, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2141*8975f5c5SAndroid Build Coastguard Worker         // An INVALID_OPERATION error is generated if <texture> is the name of a buffer texture.
2142*8975f5c5SAndroid Build Coastguard Worker         if ((context->getClientVersion() >= ES_3_2 ||
2143*8975f5c5SAndroid Build Coastguard Worker              context->getExtensions().textureBufferAny()) &&
2144*8975f5c5SAndroid Build Coastguard Worker             tex->getType() == TextureType::Buffer)
2145*8975f5c5SAndroid Build Coastguard Worker         {
2146*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
2147*8975f5c5SAndroid Build Coastguard Worker             return false;
2148*8975f5c5SAndroid Build Coastguard Worker         }
2149*8975f5c5SAndroid Build Coastguard Worker 
2150*8975f5c5SAndroid Build Coastguard Worker         if (tex->getState().hasProtectedContent() != context->getState().hasProtectedContent())
2151*8975f5c5SAndroid Build Coastguard Worker         {
2152*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2153*8975f5c5SAndroid Build Coastguard Worker                                    "Mismatch between Texture and Context Protected Content state");
2154*8975f5c5SAndroid Build Coastguard Worker             return false;
2155*8975f5c5SAndroid Build Coastguard Worker         }
2156*8975f5c5SAndroid Build Coastguard Worker     }
2157*8975f5c5SAndroid Build Coastguard Worker 
2158*8975f5c5SAndroid Build Coastguard Worker     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
2159*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebuffer);
2160*8975f5c5SAndroid Build Coastguard Worker 
2161*8975f5c5SAndroid Build Coastguard Worker     if (framebuffer->isDefault())
2162*8975f5c5SAndroid Build Coastguard Worker     {
2163*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
2164*8975f5c5SAndroid Build Coastguard Worker         return false;
2165*8975f5c5SAndroid Build Coastguard Worker     }
2166*8975f5c5SAndroid Build Coastguard Worker 
2167*8975f5c5SAndroid Build Coastguard Worker     return true;
2168*8975f5c5SAndroid Build Coastguard Worker }
2169*8975f5c5SAndroid Build Coastguard Worker 
ValidateGenerateMipmapBase(const Context * context,angle::EntryPoint entryPoint,TextureType target)2170*8975f5c5SAndroid Build Coastguard Worker bool ValidateGenerateMipmapBase(const Context *context,
2171*8975f5c5SAndroid Build Coastguard Worker                                 angle::EntryPoint entryPoint,
2172*8975f5c5SAndroid Build Coastguard Worker                                 TextureType target)
2173*8975f5c5SAndroid Build Coastguard Worker {
2174*8975f5c5SAndroid Build Coastguard Worker     if (!ValidTextureTarget(context, target))
2175*8975f5c5SAndroid Build Coastguard Worker     {
2176*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
2177*8975f5c5SAndroid Build Coastguard Worker         return false;
2178*8975f5c5SAndroid Build Coastguard Worker     }
2179*8975f5c5SAndroid Build Coastguard Worker 
2180*8975f5c5SAndroid Build Coastguard Worker     Texture *texture = context->getTextureByType(target);
2181*8975f5c5SAndroid Build Coastguard Worker 
2182*8975f5c5SAndroid Build Coastguard Worker     if (texture == nullptr)
2183*8975f5c5SAndroid Build Coastguard Worker     {
2184*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureNotBound);
2185*8975f5c5SAndroid Build Coastguard Worker         return false;
2186*8975f5c5SAndroid Build Coastguard Worker     }
2187*8975f5c5SAndroid Build Coastguard Worker 
2188*8975f5c5SAndroid Build Coastguard Worker     const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
2189*8975f5c5SAndroid Build Coastguard Worker 
2190*8975f5c5SAndroid Build Coastguard Worker     // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
2191*8975f5c5SAndroid Build Coastguard Worker     // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
2192*8975f5c5SAndroid Build Coastguard Worker     if (effectiveBaseLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2193*8975f5c5SAndroid Build Coastguard Worker     {
2194*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
2195*8975f5c5SAndroid Build Coastguard Worker         return false;
2196*8975f5c5SAndroid Build Coastguard Worker     }
2197*8975f5c5SAndroid Build Coastguard Worker 
2198*8975f5c5SAndroid Build Coastguard Worker     TextureTarget baseTarget = (target == TextureType::CubeMap)
2199*8975f5c5SAndroid Build Coastguard Worker                                    ? TextureTarget::CubeMapPositiveX
2200*8975f5c5SAndroid Build Coastguard Worker                                    : NonCubeTextureTypeToTarget(target);
2201*8975f5c5SAndroid Build Coastguard Worker     const auto &format       = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
2202*8975f5c5SAndroid Build Coastguard Worker     if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
2203*8975f5c5SAndroid Build Coastguard Worker         format.stencilBits > 0)
2204*8975f5c5SAndroid Build Coastguard Worker     {
2205*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2206*8975f5c5SAndroid Build Coastguard Worker         return false;
2207*8975f5c5SAndroid Build Coastguard Worker     }
2208*8975f5c5SAndroid Build Coastguard Worker 
2209*8975f5c5SAndroid Build Coastguard Worker     // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
2210*8975f5c5SAndroid Build Coastguard Worker     bool formatUnsized = !format.sized;
2211*8975f5c5SAndroid Build Coastguard Worker     bool formatColorRenderableAndFilterable =
2212*8975f5c5SAndroid Build Coastguard Worker         format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
2213*8975f5c5SAndroid Build Coastguard Worker         format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
2214*8975f5c5SAndroid Build Coastguard Worker     if (!formatUnsized && !formatColorRenderableAndFilterable)
2215*8975f5c5SAndroid Build Coastguard Worker     {
2216*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2217*8975f5c5SAndroid Build Coastguard Worker         return false;
2218*8975f5c5SAndroid Build Coastguard Worker     }
2219*8975f5c5SAndroid Build Coastguard Worker 
2220*8975f5c5SAndroid Build Coastguard Worker     // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
2221*8975f5c5SAndroid Build Coastguard Worker     // generation
2222*8975f5c5SAndroid Build Coastguard Worker     if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
2223*8975f5c5SAndroid Build Coastguard Worker     {
2224*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2225*8975f5c5SAndroid Build Coastguard Worker         return false;
2226*8975f5c5SAndroid Build Coastguard Worker     }
2227*8975f5c5SAndroid Build Coastguard Worker 
2228*8975f5c5SAndroid Build Coastguard Worker     // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
2229*8975f5c5SAndroid Build Coastguard Worker     // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
2230*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
2231*8975f5c5SAndroid Build Coastguard Worker     {
2232*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
2233*8975f5c5SAndroid Build Coastguard Worker         return false;
2234*8975f5c5SAndroid Build Coastguard Worker     }
2235*8975f5c5SAndroid Build Coastguard Worker 
2236*8975f5c5SAndroid Build Coastguard Worker     // Non-power of 2 ES2 check
2237*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNpotOES &&
2238*8975f5c5SAndroid Build Coastguard Worker         (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
2239*8975f5c5SAndroid Build Coastguard Worker          !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
2240*8975f5c5SAndroid Build Coastguard Worker     {
2241*8975f5c5SAndroid Build Coastguard Worker         ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
2242*8975f5c5SAndroid Build Coastguard Worker                target == TextureType::CubeMap);
2243*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureNotPow2);
2244*8975f5c5SAndroid Build Coastguard Worker         return false;
2245*8975f5c5SAndroid Build Coastguard Worker     }
2246*8975f5c5SAndroid Build Coastguard Worker 
2247*8975f5c5SAndroid Build Coastguard Worker     // Cube completeness check
2248*8975f5c5SAndroid Build Coastguard Worker     if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
2249*8975f5c5SAndroid Build Coastguard Worker     {
2250*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCubemapIncomplete);
2251*8975f5c5SAndroid Build Coastguard Worker         return false;
2252*8975f5c5SAndroid Build Coastguard Worker     }
2253*8975f5c5SAndroid Build Coastguard Worker 
2254*8975f5c5SAndroid Build Coastguard Worker     if (context->isWebGL() && (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
2255*8975f5c5SAndroid Build Coastguard Worker                                texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
2256*8975f5c5SAndroid Build Coastguard Worker     {
2257*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
2258*8975f5c5SAndroid Build Coastguard Worker         return false;
2259*8975f5c5SAndroid Build Coastguard Worker     }
2260*8975f5c5SAndroid Build Coastguard Worker 
2261*8975f5c5SAndroid Build Coastguard Worker     return true;
2262*8975f5c5SAndroid Build Coastguard Worker }
2263*8975f5c5SAndroid Build Coastguard Worker 
ValidateReadPixelsRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const GLsizei * length,const GLsizei * columns,const GLsizei * rows,const void * pixels)2264*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadPixelsRobustANGLE(const Context *context,
2265*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
2266*8975f5c5SAndroid Build Coastguard Worker                                    GLint x,
2267*8975f5c5SAndroid Build Coastguard Worker                                    GLint y,
2268*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei width,
2269*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei height,
2270*8975f5c5SAndroid Build Coastguard Worker                                    GLenum format,
2271*8975f5c5SAndroid Build Coastguard Worker                                    GLenum type,
2272*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei bufSize,
2273*8975f5c5SAndroid Build Coastguard Worker                                    const GLsizei *length,
2274*8975f5c5SAndroid Build Coastguard Worker                                    const GLsizei *columns,
2275*8975f5c5SAndroid Build Coastguard Worker                                    const GLsizei *rows,
2276*8975f5c5SAndroid Build Coastguard Worker                                    const void *pixels)
2277*8975f5c5SAndroid Build Coastguard Worker {
2278*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2279*8975f5c5SAndroid Build Coastguard Worker     {
2280*8975f5c5SAndroid Build Coastguard Worker         return false;
2281*8975f5c5SAndroid Build Coastguard Worker     }
2282*8975f5c5SAndroid Build Coastguard Worker 
2283*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength  = 0;
2284*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeColumns = 0;
2285*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeRows    = 0;
2286*8975f5c5SAndroid Build Coastguard Worker 
2287*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
2288*8975f5c5SAndroid Build Coastguard Worker                                 &writeLength, &writeColumns, &writeRows, pixels))
2289*8975f5c5SAndroid Build Coastguard Worker     {
2290*8975f5c5SAndroid Build Coastguard Worker         return false;
2291*8975f5c5SAndroid Build Coastguard Worker     }
2292*8975f5c5SAndroid Build Coastguard Worker 
2293*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
2294*8975f5c5SAndroid Build Coastguard Worker     {
2295*8975f5c5SAndroid Build Coastguard Worker         return false;
2296*8975f5c5SAndroid Build Coastguard Worker     }
2297*8975f5c5SAndroid Build Coastguard Worker 
2298*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
2299*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(columns, writeColumns);
2300*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(rows, writeRows);
2301*8975f5c5SAndroid Build Coastguard Worker 
2302*8975f5c5SAndroid Build Coastguard Worker     return true;
2303*8975f5c5SAndroid Build Coastguard Worker }
2304*8975f5c5SAndroid Build Coastguard Worker 
ValidateReadnPixelsEXT(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)2305*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadnPixelsEXT(const Context *context,
2306*8975f5c5SAndroid Build Coastguard Worker                             angle::EntryPoint entryPoint,
2307*8975f5c5SAndroid Build Coastguard Worker                             GLint x,
2308*8975f5c5SAndroid Build Coastguard Worker                             GLint y,
2309*8975f5c5SAndroid Build Coastguard Worker                             GLsizei width,
2310*8975f5c5SAndroid Build Coastguard Worker                             GLsizei height,
2311*8975f5c5SAndroid Build Coastguard Worker                             GLenum format,
2312*8975f5c5SAndroid Build Coastguard Worker                             GLenum type,
2313*8975f5c5SAndroid Build Coastguard Worker                             GLsizei bufSize,
2314*8975f5c5SAndroid Build Coastguard Worker                             const void *pixels)
2315*8975f5c5SAndroid Build Coastguard Worker {
2316*8975f5c5SAndroid Build Coastguard Worker     if (bufSize < 0)
2317*8975f5c5SAndroid Build Coastguard Worker     {
2318*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
2319*8975f5c5SAndroid Build Coastguard Worker         return false;
2320*8975f5c5SAndroid Build Coastguard Worker     }
2321*8975f5c5SAndroid Build Coastguard Worker 
2322*8975f5c5SAndroid Build Coastguard Worker     return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
2323*8975f5c5SAndroid Build Coastguard Worker                                   nullptr, nullptr, nullptr, pixels);
2324*8975f5c5SAndroid Build Coastguard Worker }
2325*8975f5c5SAndroid Build Coastguard Worker 
ValidateReadnPixelsRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const GLsizei * length,const GLsizei * columns,const GLsizei * rows,const void * data)2326*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadnPixelsRobustANGLE(const Context *context,
2327*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
2328*8975f5c5SAndroid Build Coastguard Worker                                     GLint x,
2329*8975f5c5SAndroid Build Coastguard Worker                                     GLint y,
2330*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei width,
2331*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei height,
2332*8975f5c5SAndroid Build Coastguard Worker                                     GLenum format,
2333*8975f5c5SAndroid Build Coastguard Worker                                     GLenum type,
2334*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei bufSize,
2335*8975f5c5SAndroid Build Coastguard Worker                                     const GLsizei *length,
2336*8975f5c5SAndroid Build Coastguard Worker                                     const GLsizei *columns,
2337*8975f5c5SAndroid Build Coastguard Worker                                     const GLsizei *rows,
2338*8975f5c5SAndroid Build Coastguard Worker                                     const void *data)
2339*8975f5c5SAndroid Build Coastguard Worker {
2340*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength  = 0;
2341*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeColumns = 0;
2342*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeRows    = 0;
2343*8975f5c5SAndroid Build Coastguard Worker 
2344*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2345*8975f5c5SAndroid Build Coastguard Worker     {
2346*8975f5c5SAndroid Build Coastguard Worker         return false;
2347*8975f5c5SAndroid Build Coastguard Worker     }
2348*8975f5c5SAndroid Build Coastguard Worker 
2349*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
2350*8975f5c5SAndroid Build Coastguard Worker                                 &writeLength, &writeColumns, &writeRows, data))
2351*8975f5c5SAndroid Build Coastguard Worker     {
2352*8975f5c5SAndroid Build Coastguard Worker         return false;
2353*8975f5c5SAndroid Build Coastguard Worker     }
2354*8975f5c5SAndroid Build Coastguard Worker 
2355*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
2356*8975f5c5SAndroid Build Coastguard Worker     {
2357*8975f5c5SAndroid Build Coastguard Worker         return false;
2358*8975f5c5SAndroid Build Coastguard Worker     }
2359*8975f5c5SAndroid Build Coastguard Worker 
2360*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
2361*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(columns, writeColumns);
2362*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(rows, writeRows);
2363*8975f5c5SAndroid Build Coastguard Worker 
2364*8975f5c5SAndroid Build Coastguard Worker     return true;
2365*8975f5c5SAndroid Build Coastguard Worker }
2366*8975f5c5SAndroid Build Coastguard Worker 
ValidateGenQueriesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const QueryID * ids)2367*8975f5c5SAndroid Build Coastguard Worker bool ValidateGenQueriesEXT(const Context *context,
2368*8975f5c5SAndroid Build Coastguard Worker                            angle::EntryPoint entryPoint,
2369*8975f5c5SAndroid Build Coastguard Worker                            GLsizei n,
2370*8975f5c5SAndroid Build Coastguard Worker                            const QueryID *ids)
2371*8975f5c5SAndroid Build Coastguard Worker {
2372*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().occlusionQueryBooleanEXT &&
2373*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().disjointTimerQueryEXT)
2374*8975f5c5SAndroid Build Coastguard Worker     {
2375*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2376*8975f5c5SAndroid Build Coastguard Worker         return false;
2377*8975f5c5SAndroid Build Coastguard Worker     }
2378*8975f5c5SAndroid Build Coastguard Worker 
2379*8975f5c5SAndroid Build Coastguard Worker     return ValidateGenOrDelete(context, entryPoint, n);
2380*8975f5c5SAndroid Build Coastguard Worker }
2381*8975f5c5SAndroid Build Coastguard Worker 
ValidateDeleteQueriesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const QueryID * ids)2382*8975f5c5SAndroid Build Coastguard Worker bool ValidateDeleteQueriesEXT(const Context *context,
2383*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
2384*8975f5c5SAndroid Build Coastguard Worker                               GLsizei n,
2385*8975f5c5SAndroid Build Coastguard Worker                               const QueryID *ids)
2386*8975f5c5SAndroid Build Coastguard Worker {
2387*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().occlusionQueryBooleanEXT &&
2388*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().disjointTimerQueryEXT)
2389*8975f5c5SAndroid Build Coastguard Worker     {
2390*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2391*8975f5c5SAndroid Build Coastguard Worker         return false;
2392*8975f5c5SAndroid Build Coastguard Worker     }
2393*8975f5c5SAndroid Build Coastguard Worker 
2394*8975f5c5SAndroid Build Coastguard Worker     return ValidateGenOrDelete(context, entryPoint, n);
2395*8975f5c5SAndroid Build Coastguard Worker }
2396*8975f5c5SAndroid Build Coastguard Worker 
ValidateIsQueryEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id)2397*8975f5c5SAndroid Build Coastguard Worker bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id)
2398*8975f5c5SAndroid Build Coastguard Worker {
2399*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().occlusionQueryBooleanEXT &&
2400*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().disjointTimerQueryEXT)
2401*8975f5c5SAndroid Build Coastguard Worker     {
2402*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2403*8975f5c5SAndroid Build Coastguard Worker         return false;
2404*8975f5c5SAndroid Build Coastguard Worker     }
2405*8975f5c5SAndroid Build Coastguard Worker 
2406*8975f5c5SAndroid Build Coastguard Worker     return true;
2407*8975f5c5SAndroid Build Coastguard Worker }
2408*8975f5c5SAndroid Build Coastguard Worker 
ValidateBeginQueryBase(const Context * context,angle::EntryPoint entryPoint,QueryType target,QueryID id)2409*8975f5c5SAndroid Build Coastguard Worker bool ValidateBeginQueryBase(const Context *context,
2410*8975f5c5SAndroid Build Coastguard Worker                             angle::EntryPoint entryPoint,
2411*8975f5c5SAndroid Build Coastguard Worker                             QueryType target,
2412*8975f5c5SAndroid Build Coastguard Worker                             QueryID id)
2413*8975f5c5SAndroid Build Coastguard Worker {
2414*8975f5c5SAndroid Build Coastguard Worker     if (!ValidQueryType(context, target))
2415*8975f5c5SAndroid Build Coastguard Worker     {
2416*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryType);
2417*8975f5c5SAndroid Build Coastguard Worker         return false;
2418*8975f5c5SAndroid Build Coastguard Worker     }
2419*8975f5c5SAndroid Build Coastguard Worker 
2420*8975f5c5SAndroid Build Coastguard Worker     if (id.value == 0)
2421*8975f5c5SAndroid Build Coastguard Worker     {
2422*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2423*8975f5c5SAndroid Build Coastguard Worker         return false;
2424*8975f5c5SAndroid Build Coastguard Worker     }
2425*8975f5c5SAndroid Build Coastguard Worker 
2426*8975f5c5SAndroid Build Coastguard Worker     // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
2427*8975f5c5SAndroid Build Coastguard Worker     // of zero, if the active query object name for <target> is non-zero (for the
2428*8975f5c5SAndroid Build Coastguard Worker     // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
2429*8975f5c5SAndroid Build Coastguard Worker     // the active query for either target is non-zero), if <id> is the name of an
2430*8975f5c5SAndroid Build Coastguard Worker     // existing query object whose type does not match <target>, or if <id> is the
2431*8975f5c5SAndroid Build Coastguard Worker     // active query object name for any query type, the error INVALID_OPERATION is
2432*8975f5c5SAndroid Build Coastguard Worker     // generated.
2433*8975f5c5SAndroid Build Coastguard Worker 
2434*8975f5c5SAndroid Build Coastguard Worker     // Ensure no other queries are active
2435*8975f5c5SAndroid Build Coastguard Worker     // NOTE: If other queries than occlusion are supported, we will need to check
2436*8975f5c5SAndroid Build Coastguard Worker     // separately that:
2437*8975f5c5SAndroid Build Coastguard Worker     //    a) The query ID passed is not the current active query for any target/type
2438*8975f5c5SAndroid Build Coastguard Worker     //    b) There are no active queries for the requested target (and in the case
2439*8975f5c5SAndroid Build Coastguard Worker     //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
2440*8975f5c5SAndroid Build Coastguard Worker     //       no query may be active for either if glBeginQuery targets either.
2441*8975f5c5SAndroid Build Coastguard Worker 
2442*8975f5c5SAndroid Build Coastguard Worker     if (context->getState().isQueryActive(target))
2443*8975f5c5SAndroid Build Coastguard Worker     {
2444*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kOtherQueryActive);
2445*8975f5c5SAndroid Build Coastguard Worker         return false;
2446*8975f5c5SAndroid Build Coastguard Worker     }
2447*8975f5c5SAndroid Build Coastguard Worker 
2448*8975f5c5SAndroid Build Coastguard Worker     // check that name was obtained with glGenQueries
2449*8975f5c5SAndroid Build Coastguard Worker     if (!context->isQueryGenerated(id))
2450*8975f5c5SAndroid Build Coastguard Worker     {
2451*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2452*8975f5c5SAndroid Build Coastguard Worker         return false;
2453*8975f5c5SAndroid Build Coastguard Worker     }
2454*8975f5c5SAndroid Build Coastguard Worker 
2455*8975f5c5SAndroid Build Coastguard Worker     // Check for type mismatch. If query is not yet started we're good to go.
2456*8975f5c5SAndroid Build Coastguard Worker     Query *queryObject = context->getQuery(id);
2457*8975f5c5SAndroid Build Coastguard Worker     if (queryObject && queryObject->getType() != target)
2458*8975f5c5SAndroid Build Coastguard Worker     {
2459*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryTargetMismatch);
2460*8975f5c5SAndroid Build Coastguard Worker         return false;
2461*8975f5c5SAndroid Build Coastguard Worker     }
2462*8975f5c5SAndroid Build Coastguard Worker 
2463*8975f5c5SAndroid Build Coastguard Worker     return true;
2464*8975f5c5SAndroid Build Coastguard Worker }
2465*8975f5c5SAndroid Build Coastguard Worker 
ValidateBeginQueryEXT(const Context * context,angle::EntryPoint entryPoint,QueryType target,QueryID id)2466*8975f5c5SAndroid Build Coastguard Worker bool ValidateBeginQueryEXT(const Context *context,
2467*8975f5c5SAndroid Build Coastguard Worker                            angle::EntryPoint entryPoint,
2468*8975f5c5SAndroid Build Coastguard Worker                            QueryType target,
2469*8975f5c5SAndroid Build Coastguard Worker                            QueryID id)
2470*8975f5c5SAndroid Build Coastguard Worker {
2471*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().occlusionQueryBooleanEXT &&
2472*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().disjointTimerQueryEXT &&
2473*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().syncQueryCHROMIUM)
2474*8975f5c5SAndroid Build Coastguard Worker     {
2475*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2476*8975f5c5SAndroid Build Coastguard Worker         return false;
2477*8975f5c5SAndroid Build Coastguard Worker     }
2478*8975f5c5SAndroid Build Coastguard Worker 
2479*8975f5c5SAndroid Build Coastguard Worker     return ValidateBeginQueryBase(context, entryPoint, target, id);
2480*8975f5c5SAndroid Build Coastguard Worker }
2481*8975f5c5SAndroid Build Coastguard Worker 
ValidateEndQueryBase(const Context * context,angle::EntryPoint entryPoint,QueryType target)2482*8975f5c5SAndroid Build Coastguard Worker bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target)
2483*8975f5c5SAndroid Build Coastguard Worker {
2484*8975f5c5SAndroid Build Coastguard Worker     if (!ValidQueryType(context, target))
2485*8975f5c5SAndroid Build Coastguard Worker     {
2486*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryType);
2487*8975f5c5SAndroid Build Coastguard Worker         return false;
2488*8975f5c5SAndroid Build Coastguard Worker     }
2489*8975f5c5SAndroid Build Coastguard Worker 
2490*8975f5c5SAndroid Build Coastguard Worker     const Query *queryObject = context->getState().getActiveQuery(target);
2491*8975f5c5SAndroid Build Coastguard Worker 
2492*8975f5c5SAndroid Build Coastguard Worker     if (queryObject == nullptr)
2493*8975f5c5SAndroid Build Coastguard Worker     {
2494*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryInactive);
2495*8975f5c5SAndroid Build Coastguard Worker         return false;
2496*8975f5c5SAndroid Build Coastguard Worker     }
2497*8975f5c5SAndroid Build Coastguard Worker 
2498*8975f5c5SAndroid Build Coastguard Worker     return true;
2499*8975f5c5SAndroid Build Coastguard Worker }
2500*8975f5c5SAndroid Build Coastguard Worker 
ValidateEndQueryEXT(const Context * context,angle::EntryPoint entryPoint,QueryType target)2501*8975f5c5SAndroid Build Coastguard Worker bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target)
2502*8975f5c5SAndroid Build Coastguard Worker {
2503*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().occlusionQueryBooleanEXT &&
2504*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().disjointTimerQueryEXT &&
2505*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().syncQueryCHROMIUM)
2506*8975f5c5SAndroid Build Coastguard Worker     {
2507*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
2508*8975f5c5SAndroid Build Coastguard Worker         return false;
2509*8975f5c5SAndroid Build Coastguard Worker     }
2510*8975f5c5SAndroid Build Coastguard Worker 
2511*8975f5c5SAndroid Build Coastguard Worker     return ValidateEndQueryBase(context, entryPoint, target);
2512*8975f5c5SAndroid Build Coastguard Worker }
2513*8975f5c5SAndroid Build Coastguard Worker 
ValidateQueryCounterEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,QueryType target)2514*8975f5c5SAndroid Build Coastguard Worker bool ValidateQueryCounterEXT(const Context *context,
2515*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
2516*8975f5c5SAndroid Build Coastguard Worker                              QueryID id,
2517*8975f5c5SAndroid Build Coastguard Worker                              QueryType target)
2518*8975f5c5SAndroid Build Coastguard Worker {
2519*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2520*8975f5c5SAndroid Build Coastguard Worker     {
2521*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2522*8975f5c5SAndroid Build Coastguard Worker         return false;
2523*8975f5c5SAndroid Build Coastguard Worker     }
2524*8975f5c5SAndroid Build Coastguard Worker 
2525*8975f5c5SAndroid Build Coastguard Worker     if (target != QueryType::Timestamp)
2526*8975f5c5SAndroid Build Coastguard Worker     {
2527*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryTarget);
2528*8975f5c5SAndroid Build Coastguard Worker         return false;
2529*8975f5c5SAndroid Build Coastguard Worker     }
2530*8975f5c5SAndroid Build Coastguard Worker 
2531*8975f5c5SAndroid Build Coastguard Worker     if (!context->isQueryGenerated(id))
2532*8975f5c5SAndroid Build Coastguard Worker     {
2533*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2534*8975f5c5SAndroid Build Coastguard Worker         return false;
2535*8975f5c5SAndroid Build Coastguard Worker     }
2536*8975f5c5SAndroid Build Coastguard Worker 
2537*8975f5c5SAndroid Build Coastguard Worker     // If query object is not started, that's fine.
2538*8975f5c5SAndroid Build Coastguard Worker     Query *queryObject = context->getQuery(id);
2539*8975f5c5SAndroid Build Coastguard Worker     if (queryObject && context->getState().isQueryActive(queryObject))
2540*8975f5c5SAndroid Build Coastguard Worker     {
2541*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryActive);
2542*8975f5c5SAndroid Build Coastguard Worker         return false;
2543*8975f5c5SAndroid Build Coastguard Worker     }
2544*8975f5c5SAndroid Build Coastguard Worker 
2545*8975f5c5SAndroid Build Coastguard Worker     return true;
2546*8975f5c5SAndroid Build Coastguard Worker }
2547*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryivBase(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,GLsizei * numParams)2548*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryivBase(const Context *context,
2549*8975f5c5SAndroid Build Coastguard Worker                             angle::EntryPoint entryPoint,
2550*8975f5c5SAndroid Build Coastguard Worker                             QueryType target,
2551*8975f5c5SAndroid Build Coastguard Worker                             GLenum pname,
2552*8975f5c5SAndroid Build Coastguard Worker                             GLsizei *numParams)
2553*8975f5c5SAndroid Build Coastguard Worker {
2554*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
2555*8975f5c5SAndroid Build Coastguard Worker     {
2556*8975f5c5SAndroid Build Coastguard Worker         *numParams = 0;
2557*8975f5c5SAndroid Build Coastguard Worker     }
2558*8975f5c5SAndroid Build Coastguard Worker 
2559*8975f5c5SAndroid Build Coastguard Worker     if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
2560*8975f5c5SAndroid Build Coastguard Worker     {
2561*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryType);
2562*8975f5c5SAndroid Build Coastguard Worker         return false;
2563*8975f5c5SAndroid Build Coastguard Worker     }
2564*8975f5c5SAndroid Build Coastguard Worker 
2565*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
2566*8975f5c5SAndroid Build Coastguard Worker     {
2567*8975f5c5SAndroid Build Coastguard Worker         case GL_CURRENT_QUERY_EXT:
2568*8975f5c5SAndroid Build Coastguard Worker             if (target == QueryType::Timestamp)
2569*8975f5c5SAndroid Build Coastguard Worker             {
2570*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidQueryTarget);
2571*8975f5c5SAndroid Build Coastguard Worker                 return false;
2572*8975f5c5SAndroid Build Coastguard Worker             }
2573*8975f5c5SAndroid Build Coastguard Worker             break;
2574*8975f5c5SAndroid Build Coastguard Worker         case GL_QUERY_COUNTER_BITS_EXT:
2575*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().disjointTimerQueryEXT ||
2576*8975f5c5SAndroid Build Coastguard Worker                 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
2577*8975f5c5SAndroid Build Coastguard Worker             {
2578*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2579*8975f5c5SAndroid Build Coastguard Worker                 return false;
2580*8975f5c5SAndroid Build Coastguard Worker             }
2581*8975f5c5SAndroid Build Coastguard Worker             break;
2582*8975f5c5SAndroid Build Coastguard Worker         default:
2583*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2584*8975f5c5SAndroid Build Coastguard Worker             return false;
2585*8975f5c5SAndroid Build Coastguard Worker     }
2586*8975f5c5SAndroid Build Coastguard Worker 
2587*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
2588*8975f5c5SAndroid Build Coastguard Worker     {
2589*8975f5c5SAndroid Build Coastguard Worker         // All queries return only one value
2590*8975f5c5SAndroid Build Coastguard Worker         *numParams = 1;
2591*8975f5c5SAndroid Build Coastguard Worker     }
2592*8975f5c5SAndroid Build Coastguard Worker 
2593*8975f5c5SAndroid Build Coastguard Worker     return true;
2594*8975f5c5SAndroid Build Coastguard Worker }
2595*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryivEXT(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,const GLint * params)2596*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryivEXT(const Context *context,
2597*8975f5c5SAndroid Build Coastguard Worker                            angle::EntryPoint entryPoint,
2598*8975f5c5SAndroid Build Coastguard Worker                            QueryType target,
2599*8975f5c5SAndroid Build Coastguard Worker                            GLenum pname,
2600*8975f5c5SAndroid Build Coastguard Worker                            const GLint *params)
2601*8975f5c5SAndroid Build Coastguard Worker {
2602*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().occlusionQueryBooleanEXT &&
2603*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().disjointTimerQueryEXT &&
2604*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().syncQueryCHROMIUM)
2605*8975f5c5SAndroid Build Coastguard Worker     {
2606*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2607*8975f5c5SAndroid Build Coastguard Worker         return false;
2608*8975f5c5SAndroid Build Coastguard Worker     }
2609*8975f5c5SAndroid Build Coastguard Worker 
2610*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr);
2611*8975f5c5SAndroid Build Coastguard Worker }
2612*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2613*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryivRobustANGLE(const Context *context,
2614*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
2615*8975f5c5SAndroid Build Coastguard Worker                                    QueryType target,
2616*8975f5c5SAndroid Build Coastguard Worker                                    GLenum pname,
2617*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei bufSize,
2618*8975f5c5SAndroid Build Coastguard Worker                                    const GLsizei *length,
2619*8975f5c5SAndroid Build Coastguard Worker                                    const GLint *params)
2620*8975f5c5SAndroid Build Coastguard Worker {
2621*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2622*8975f5c5SAndroid Build Coastguard Worker     {
2623*8975f5c5SAndroid Build Coastguard Worker         return false;
2624*8975f5c5SAndroid Build Coastguard Worker     }
2625*8975f5c5SAndroid Build Coastguard Worker 
2626*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
2627*8975f5c5SAndroid Build Coastguard Worker 
2628*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetQueryivBase(context, entryPoint, target, pname, &numParams))
2629*8975f5c5SAndroid Build Coastguard Worker     {
2630*8975f5c5SAndroid Build Coastguard Worker         return false;
2631*8975f5c5SAndroid Build Coastguard Worker     }
2632*8975f5c5SAndroid Build Coastguard Worker 
2633*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2634*8975f5c5SAndroid Build Coastguard Worker     {
2635*8975f5c5SAndroid Build Coastguard Worker         return false;
2636*8975f5c5SAndroid Build Coastguard Worker     }
2637*8975f5c5SAndroid Build Coastguard Worker 
2638*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
2639*8975f5c5SAndroid Build Coastguard Worker 
2640*8975f5c5SAndroid Build Coastguard Worker     return true;
2641*8975f5c5SAndroid Build Coastguard Worker }
2642*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectValueBase(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei * numParams)2643*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectValueBase(const Context *context,
2644*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
2645*8975f5c5SAndroid Build Coastguard Worker                                      QueryID id,
2646*8975f5c5SAndroid Build Coastguard Worker                                      GLenum pname,
2647*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei *numParams)
2648*8975f5c5SAndroid Build Coastguard Worker {
2649*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
2650*8975f5c5SAndroid Build Coastguard Worker     {
2651*8975f5c5SAndroid Build Coastguard Worker         *numParams = 1;
2652*8975f5c5SAndroid Build Coastguard Worker     }
2653*8975f5c5SAndroid Build Coastguard Worker 
2654*8975f5c5SAndroid Build Coastguard Worker     if (context->isContextLost())
2655*8975f5c5SAndroid Build Coastguard Worker     {
2656*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
2657*8975f5c5SAndroid Build Coastguard Worker 
2658*8975f5c5SAndroid Build Coastguard Worker         if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
2659*8975f5c5SAndroid Build Coastguard Worker         {
2660*8975f5c5SAndroid Build Coastguard Worker             // Generate an error but still return true, the context still needs to return a
2661*8975f5c5SAndroid Build Coastguard Worker             // value in this case.
2662*8975f5c5SAndroid Build Coastguard Worker             return true;
2663*8975f5c5SAndroid Build Coastguard Worker         }
2664*8975f5c5SAndroid Build Coastguard Worker         else
2665*8975f5c5SAndroid Build Coastguard Worker         {
2666*8975f5c5SAndroid Build Coastguard Worker             return false;
2667*8975f5c5SAndroid Build Coastguard Worker         }
2668*8975f5c5SAndroid Build Coastguard Worker     }
2669*8975f5c5SAndroid Build Coastguard Worker 
2670*8975f5c5SAndroid Build Coastguard Worker     Query *queryObject = context->getQuery(id);
2671*8975f5c5SAndroid Build Coastguard Worker 
2672*8975f5c5SAndroid Build Coastguard Worker     if (!queryObject)
2673*8975f5c5SAndroid Build Coastguard Worker     {
2674*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryId);
2675*8975f5c5SAndroid Build Coastguard Worker         return false;
2676*8975f5c5SAndroid Build Coastguard Worker     }
2677*8975f5c5SAndroid Build Coastguard Worker 
2678*8975f5c5SAndroid Build Coastguard Worker     if (context->getState().isQueryActive(queryObject))
2679*8975f5c5SAndroid Build Coastguard Worker     {
2680*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kQueryActive);
2681*8975f5c5SAndroid Build Coastguard Worker         return false;
2682*8975f5c5SAndroid Build Coastguard Worker     }
2683*8975f5c5SAndroid Build Coastguard Worker 
2684*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
2685*8975f5c5SAndroid Build Coastguard Worker     {
2686*8975f5c5SAndroid Build Coastguard Worker         case GL_QUERY_RESULT_EXT:
2687*8975f5c5SAndroid Build Coastguard Worker         case GL_QUERY_RESULT_AVAILABLE_EXT:
2688*8975f5c5SAndroid Build Coastguard Worker             break;
2689*8975f5c5SAndroid Build Coastguard Worker 
2690*8975f5c5SAndroid Build Coastguard Worker         default:
2691*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2692*8975f5c5SAndroid Build Coastguard Worker             return false;
2693*8975f5c5SAndroid Build Coastguard Worker     }
2694*8975f5c5SAndroid Build Coastguard Worker 
2695*8975f5c5SAndroid Build Coastguard Worker     return true;
2696*8975f5c5SAndroid Build Coastguard Worker }
2697*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectivEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,const GLint * params)2698*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectivEXT(const Context *context,
2699*8975f5c5SAndroid Build Coastguard Worker                                  angle::EntryPoint entryPoint,
2700*8975f5c5SAndroid Build Coastguard Worker                                  QueryID id,
2701*8975f5c5SAndroid Build Coastguard Worker                                  GLenum pname,
2702*8975f5c5SAndroid Build Coastguard Worker                                  const GLint *params)
2703*8975f5c5SAndroid Build Coastguard Worker {
2704*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2705*8975f5c5SAndroid Build Coastguard Worker     {
2706*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2707*8975f5c5SAndroid Build Coastguard Worker         return false;
2708*8975f5c5SAndroid Build Coastguard Worker     }
2709*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2710*8975f5c5SAndroid Build Coastguard Worker }
2711*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2712*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
2713*8975f5c5SAndroid Build Coastguard Worker                                          angle::EntryPoint entryPoint,
2714*8975f5c5SAndroid Build Coastguard Worker                                          QueryID id,
2715*8975f5c5SAndroid Build Coastguard Worker                                          GLenum pname,
2716*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei bufSize,
2717*8975f5c5SAndroid Build Coastguard Worker                                          const GLsizei *length,
2718*8975f5c5SAndroid Build Coastguard Worker                                          const GLint *params)
2719*8975f5c5SAndroid Build Coastguard Worker {
2720*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2721*8975f5c5SAndroid Build Coastguard Worker     {
2722*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2723*8975f5c5SAndroid Build Coastguard Worker         return false;
2724*8975f5c5SAndroid Build Coastguard Worker     }
2725*8975f5c5SAndroid Build Coastguard Worker 
2726*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2727*8975f5c5SAndroid Build Coastguard Worker     {
2728*8975f5c5SAndroid Build Coastguard Worker         return false;
2729*8975f5c5SAndroid Build Coastguard Worker     }
2730*8975f5c5SAndroid Build Coastguard Worker 
2731*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
2732*8975f5c5SAndroid Build Coastguard Worker 
2733*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2734*8975f5c5SAndroid Build Coastguard Worker     {
2735*8975f5c5SAndroid Build Coastguard Worker         return false;
2736*8975f5c5SAndroid Build Coastguard Worker     }
2737*8975f5c5SAndroid Build Coastguard Worker 
2738*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2739*8975f5c5SAndroid Build Coastguard Worker     {
2740*8975f5c5SAndroid Build Coastguard Worker         return false;
2741*8975f5c5SAndroid Build Coastguard Worker     }
2742*8975f5c5SAndroid Build Coastguard Worker 
2743*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
2744*8975f5c5SAndroid Build Coastguard Worker 
2745*8975f5c5SAndroid Build Coastguard Worker     return true;
2746*8975f5c5SAndroid Build Coastguard Worker }
2747*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectuivEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,const GLuint * params)2748*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectuivEXT(const Context *context,
2749*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
2750*8975f5c5SAndroid Build Coastguard Worker                                   QueryID id,
2751*8975f5c5SAndroid Build Coastguard Worker                                   GLenum pname,
2752*8975f5c5SAndroid Build Coastguard Worker                                   const GLuint *params)
2753*8975f5c5SAndroid Build Coastguard Worker {
2754*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT &&
2755*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().occlusionQueryBooleanEXT &&
2756*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().syncQueryCHROMIUM)
2757*8975f5c5SAndroid Build Coastguard Worker     {
2758*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2759*8975f5c5SAndroid Build Coastguard Worker         return false;
2760*8975f5c5SAndroid Build Coastguard Worker     }
2761*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2762*8975f5c5SAndroid Build Coastguard Worker }
2763*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)2764*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
2765*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
2766*8975f5c5SAndroid Build Coastguard Worker                                           QueryID id,
2767*8975f5c5SAndroid Build Coastguard Worker                                           GLenum pname,
2768*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei bufSize,
2769*8975f5c5SAndroid Build Coastguard Worker                                           const GLsizei *length,
2770*8975f5c5SAndroid Build Coastguard Worker                                           const GLuint *params)
2771*8975f5c5SAndroid Build Coastguard Worker {
2772*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT &&
2773*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().occlusionQueryBooleanEXT &&
2774*8975f5c5SAndroid Build Coastguard Worker         !context->getExtensions().syncQueryCHROMIUM)
2775*8975f5c5SAndroid Build Coastguard Worker     {
2776*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2777*8975f5c5SAndroid Build Coastguard Worker         return false;
2778*8975f5c5SAndroid Build Coastguard Worker     }
2779*8975f5c5SAndroid Build Coastguard Worker 
2780*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2781*8975f5c5SAndroid Build Coastguard Worker     {
2782*8975f5c5SAndroid Build Coastguard Worker         return false;
2783*8975f5c5SAndroid Build Coastguard Worker     }
2784*8975f5c5SAndroid Build Coastguard Worker 
2785*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
2786*8975f5c5SAndroid Build Coastguard Worker 
2787*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2788*8975f5c5SAndroid Build Coastguard Worker     {
2789*8975f5c5SAndroid Build Coastguard Worker         return false;
2790*8975f5c5SAndroid Build Coastguard Worker     }
2791*8975f5c5SAndroid Build Coastguard Worker 
2792*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2793*8975f5c5SAndroid Build Coastguard Worker     {
2794*8975f5c5SAndroid Build Coastguard Worker         return false;
2795*8975f5c5SAndroid Build Coastguard Worker     }
2796*8975f5c5SAndroid Build Coastguard Worker 
2797*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
2798*8975f5c5SAndroid Build Coastguard Worker 
2799*8975f5c5SAndroid Build Coastguard Worker     return true;
2800*8975f5c5SAndroid Build Coastguard Worker }
2801*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjecti64vEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLint64 * params)2802*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjecti64vEXT(const Context *context,
2803*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
2804*8975f5c5SAndroid Build Coastguard Worker                                    QueryID id,
2805*8975f5c5SAndroid Build Coastguard Worker                                    GLenum pname,
2806*8975f5c5SAndroid Build Coastguard Worker                                    GLint64 *params)
2807*8975f5c5SAndroid Build Coastguard Worker {
2808*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2809*8975f5c5SAndroid Build Coastguard Worker     {
2810*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2811*8975f5c5SAndroid Build Coastguard Worker         return false;
2812*8975f5c5SAndroid Build Coastguard Worker     }
2813*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2814*8975f5c5SAndroid Build Coastguard Worker }
2815*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjecti64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,GLint64 * params)2816*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
2817*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint entryPoint,
2818*8975f5c5SAndroid Build Coastguard Worker                                            QueryID id,
2819*8975f5c5SAndroid Build Coastguard Worker                                            GLenum pname,
2820*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei bufSize,
2821*8975f5c5SAndroid Build Coastguard Worker                                            const GLsizei *length,
2822*8975f5c5SAndroid Build Coastguard Worker                                            GLint64 *params)
2823*8975f5c5SAndroid Build Coastguard Worker {
2824*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2825*8975f5c5SAndroid Build Coastguard Worker     {
2826*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2827*8975f5c5SAndroid Build Coastguard Worker         return false;
2828*8975f5c5SAndroid Build Coastguard Worker     }
2829*8975f5c5SAndroid Build Coastguard Worker 
2830*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2831*8975f5c5SAndroid Build Coastguard Worker     {
2832*8975f5c5SAndroid Build Coastguard Worker         return false;
2833*8975f5c5SAndroid Build Coastguard Worker     }
2834*8975f5c5SAndroid Build Coastguard Worker 
2835*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
2836*8975f5c5SAndroid Build Coastguard Worker 
2837*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2838*8975f5c5SAndroid Build Coastguard Worker     {
2839*8975f5c5SAndroid Build Coastguard Worker         return false;
2840*8975f5c5SAndroid Build Coastguard Worker     }
2841*8975f5c5SAndroid Build Coastguard Worker 
2842*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2843*8975f5c5SAndroid Build Coastguard Worker     {
2844*8975f5c5SAndroid Build Coastguard Worker         return false;
2845*8975f5c5SAndroid Build Coastguard Worker     }
2846*8975f5c5SAndroid Build Coastguard Worker 
2847*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
2848*8975f5c5SAndroid Build Coastguard Worker 
2849*8975f5c5SAndroid Build Coastguard Worker     return true;
2850*8975f5c5SAndroid Build Coastguard Worker }
2851*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectui64vEXT(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLuint64 * params)2852*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectui64vEXT(const Context *context,
2853*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
2854*8975f5c5SAndroid Build Coastguard Worker                                     QueryID id,
2855*8975f5c5SAndroid Build Coastguard Worker                                     GLenum pname,
2856*8975f5c5SAndroid Build Coastguard Worker                                     GLuint64 *params)
2857*8975f5c5SAndroid Build Coastguard Worker {
2858*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2859*8975f5c5SAndroid Build Coastguard Worker     {
2860*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2861*8975f5c5SAndroid Build Coastguard Worker         return false;
2862*8975f5c5SAndroid Build Coastguard Worker     }
2863*8975f5c5SAndroid Build Coastguard Worker     return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
2864*8975f5c5SAndroid Build Coastguard Worker }
2865*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetQueryObjectui64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,GLsizei bufSize,const GLsizei * length,GLuint64 * params)2866*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
2867*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
2868*8975f5c5SAndroid Build Coastguard Worker                                             QueryID id,
2869*8975f5c5SAndroid Build Coastguard Worker                                             GLenum pname,
2870*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei bufSize,
2871*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei *length,
2872*8975f5c5SAndroid Build Coastguard Worker                                             GLuint64 *params)
2873*8975f5c5SAndroid Build Coastguard Worker {
2874*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().disjointTimerQueryEXT)
2875*8975f5c5SAndroid Build Coastguard Worker     {
2876*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2877*8975f5c5SAndroid Build Coastguard Worker         return false;
2878*8975f5c5SAndroid Build Coastguard Worker     }
2879*8975f5c5SAndroid Build Coastguard Worker 
2880*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2881*8975f5c5SAndroid Build Coastguard Worker     {
2882*8975f5c5SAndroid Build Coastguard Worker         return false;
2883*8975f5c5SAndroid Build Coastguard Worker     }
2884*8975f5c5SAndroid Build Coastguard Worker 
2885*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
2886*8975f5c5SAndroid Build Coastguard Worker 
2887*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, &numParams))
2888*8975f5c5SAndroid Build Coastguard Worker     {
2889*8975f5c5SAndroid Build Coastguard Worker         return false;
2890*8975f5c5SAndroid Build Coastguard Worker     }
2891*8975f5c5SAndroid Build Coastguard Worker 
2892*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
2893*8975f5c5SAndroid Build Coastguard Worker     {
2894*8975f5c5SAndroid Build Coastguard Worker         return false;
2895*8975f5c5SAndroid Build Coastguard Worker     }
2896*8975f5c5SAndroid Build Coastguard Worker 
2897*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
2898*8975f5c5SAndroid Build Coastguard Worker 
2899*8975f5c5SAndroid Build Coastguard Worker     return true;
2900*8975f5c5SAndroid Build Coastguard Worker }
2901*8975f5c5SAndroid Build Coastguard Worker 
ValidateUniformCommonBase(const Context * context,angle::EntryPoint entryPoint,const Program * program,UniformLocation location,GLsizei count,const LinkedUniform ** uniformOut)2902*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniformCommonBase(const Context *context,
2903*8975f5c5SAndroid Build Coastguard Worker                                angle::EntryPoint entryPoint,
2904*8975f5c5SAndroid Build Coastguard Worker                                const Program *program,
2905*8975f5c5SAndroid Build Coastguard Worker                                UniformLocation location,
2906*8975f5c5SAndroid Build Coastguard Worker                                GLsizei count,
2907*8975f5c5SAndroid Build Coastguard Worker                                const LinkedUniform **uniformOut)
2908*8975f5c5SAndroid Build Coastguard Worker {
2909*8975f5c5SAndroid Build Coastguard Worker     // TODO(Jiajia): Add image uniform check in future.
2910*8975f5c5SAndroid Build Coastguard Worker     if (count < 0)
2911*8975f5c5SAndroid Build Coastguard Worker     {
2912*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
2913*8975f5c5SAndroid Build Coastguard Worker         return false;
2914*8975f5c5SAndroid Build Coastguard Worker     }
2915*8975f5c5SAndroid Build Coastguard Worker 
2916*8975f5c5SAndroid Build Coastguard Worker     if (!program)
2917*8975f5c5SAndroid Build Coastguard Worker     {
2918*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramName);
2919*8975f5c5SAndroid Build Coastguard Worker         return false;
2920*8975f5c5SAndroid Build Coastguard Worker     }
2921*8975f5c5SAndroid Build Coastguard Worker 
2922*8975f5c5SAndroid Build Coastguard Worker     if (!program->isLinked())
2923*8975f5c5SAndroid Build Coastguard Worker     {
2924*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
2925*8975f5c5SAndroid Build Coastguard Worker         return false;
2926*8975f5c5SAndroid Build Coastguard Worker     }
2927*8975f5c5SAndroid Build Coastguard Worker 
2928*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
2929*8975f5c5SAndroid Build Coastguard Worker     {
2930*8975f5c5SAndroid Build Coastguard Worker         // Silently ignore the uniform command
2931*8975f5c5SAndroid Build Coastguard Worker         return false;
2932*8975f5c5SAndroid Build Coastguard Worker     }
2933*8975f5c5SAndroid Build Coastguard Worker 
2934*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable &executable = program->getExecutable();
2935*8975f5c5SAndroid Build Coastguard Worker     const auto &uniformLocations        = executable.getUniformLocations();
2936*8975f5c5SAndroid Build Coastguard Worker     size_t castedLocation               = static_cast<size_t>(location.value);
2937*8975f5c5SAndroid Build Coastguard Worker     if (castedLocation >= uniformLocations.size())
2938*8975f5c5SAndroid Build Coastguard Worker     {
2939*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformLocation);
2940*8975f5c5SAndroid Build Coastguard Worker         return false;
2941*8975f5c5SAndroid Build Coastguard Worker     }
2942*8975f5c5SAndroid Build Coastguard Worker 
2943*8975f5c5SAndroid Build Coastguard Worker     const auto &uniformLocation = uniformLocations[castedLocation];
2944*8975f5c5SAndroid Build Coastguard Worker     if (uniformLocation.ignored)
2945*8975f5c5SAndroid Build Coastguard Worker     {
2946*8975f5c5SAndroid Build Coastguard Worker         // Silently ignore the uniform command
2947*8975f5c5SAndroid Build Coastguard Worker         return false;
2948*8975f5c5SAndroid Build Coastguard Worker     }
2949*8975f5c5SAndroid Build Coastguard Worker 
2950*8975f5c5SAndroid Build Coastguard Worker     if (!uniformLocation.used())
2951*8975f5c5SAndroid Build Coastguard Worker     {
2952*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformLocation);
2953*8975f5c5SAndroid Build Coastguard Worker         return false;
2954*8975f5c5SAndroid Build Coastguard Worker     }
2955*8975f5c5SAndroid Build Coastguard Worker 
2956*8975f5c5SAndroid Build Coastguard Worker     const LinkedUniform &uniform = executable.getUniformByIndex(uniformLocation.index);
2957*8975f5c5SAndroid Build Coastguard Worker 
2958*8975f5c5SAndroid Build Coastguard Worker     // attempting to write an array to a non-array uniform is an INVALID_OPERATION
2959*8975f5c5SAndroid Build Coastguard Worker     if (count > 1 && !uniform.isArray())
2960*8975f5c5SAndroid Build Coastguard Worker     {
2961*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformCount);
2962*8975f5c5SAndroid Build Coastguard Worker         return false;
2963*8975f5c5SAndroid Build Coastguard Worker     }
2964*8975f5c5SAndroid Build Coastguard Worker 
2965*8975f5c5SAndroid Build Coastguard Worker     *uniformOut = &uniform;
2966*8975f5c5SAndroid Build Coastguard Worker     return true;
2967*8975f5c5SAndroid Build Coastguard Worker }
2968*8975f5c5SAndroid Build Coastguard Worker 
ValidateUniform1ivValue(const Context * context,angle::EntryPoint entryPoint,GLenum uniformType,GLsizei count,const GLint * value)2969*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniform1ivValue(const Context *context,
2970*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
2971*8975f5c5SAndroid Build Coastguard Worker                              GLenum uniformType,
2972*8975f5c5SAndroid Build Coastguard Worker                              GLsizei count,
2973*8975f5c5SAndroid Build Coastguard Worker                              const GLint *value)
2974*8975f5c5SAndroid Build Coastguard Worker {
2975*8975f5c5SAndroid Build Coastguard Worker     // Value type is GL_INT, because we only get here from glUniform1i{v}.
2976*8975f5c5SAndroid Build Coastguard Worker     // It is compatible with INT or BOOL.
2977*8975f5c5SAndroid Build Coastguard Worker     // Do these cheap tests first, for a little extra speed.
2978*8975f5c5SAndroid Build Coastguard Worker     if (GL_INT == uniformType || GL_BOOL == uniformType)
2979*8975f5c5SAndroid Build Coastguard Worker     {
2980*8975f5c5SAndroid Build Coastguard Worker         return true;
2981*8975f5c5SAndroid Build Coastguard Worker     }
2982*8975f5c5SAndroid Build Coastguard Worker 
2983*8975f5c5SAndroid Build Coastguard Worker     if (IsSamplerType(uniformType))
2984*8975f5c5SAndroid Build Coastguard Worker     {
2985*8975f5c5SAndroid Build Coastguard Worker         // Check that the values are in range.
2986*8975f5c5SAndroid Build Coastguard Worker         const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2987*8975f5c5SAndroid Build Coastguard Worker         for (GLsizei i = 0; i < count; ++i)
2988*8975f5c5SAndroid Build Coastguard Worker         {
2989*8975f5c5SAndroid Build Coastguard Worker             if (value[i] < 0 || value[i] >= max)
2990*8975f5c5SAndroid Build Coastguard Worker             {
2991*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplerUniformValueOutOfRange);
2992*8975f5c5SAndroid Build Coastguard Worker                 return false;
2993*8975f5c5SAndroid Build Coastguard Worker             }
2994*8975f5c5SAndroid Build Coastguard Worker         }
2995*8975f5c5SAndroid Build Coastguard Worker         return true;
2996*8975f5c5SAndroid Build Coastguard Worker     }
2997*8975f5c5SAndroid Build Coastguard Worker 
2998*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUniformTypeMismatch);
2999*8975f5c5SAndroid Build Coastguard Worker     return false;
3000*8975f5c5SAndroid Build Coastguard Worker }
3001*8975f5c5SAndroid Build Coastguard Worker 
ValidateUniformMatrixValue(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,GLenum uniformType)3002*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniformMatrixValue(const Context *context,
3003*8975f5c5SAndroid Build Coastguard Worker                                 angle::EntryPoint entryPoint,
3004*8975f5c5SAndroid Build Coastguard Worker                                 GLenum valueType,
3005*8975f5c5SAndroid Build Coastguard Worker                                 GLenum uniformType)
3006*8975f5c5SAndroid Build Coastguard Worker {
3007*8975f5c5SAndroid Build Coastguard Worker     // Check that the value type is compatible with uniform type.
3008*8975f5c5SAndroid Build Coastguard Worker     if (valueType == uniformType)
3009*8975f5c5SAndroid Build Coastguard Worker     {
3010*8975f5c5SAndroid Build Coastguard Worker         return true;
3011*8975f5c5SAndroid Build Coastguard Worker     }
3012*8975f5c5SAndroid Build Coastguard Worker 
3013*8975f5c5SAndroid Build Coastguard Worker     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUniformTypeMismatch);
3014*8975f5c5SAndroid Build Coastguard Worker     return false;
3015*8975f5c5SAndroid Build Coastguard Worker }
3016*8975f5c5SAndroid Build Coastguard Worker 
ValidateUniform(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,UniformLocation location,GLsizei count)3017*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniform(const Context *context,
3018*8975f5c5SAndroid Build Coastguard Worker                      angle::EntryPoint entryPoint,
3019*8975f5c5SAndroid Build Coastguard Worker                      GLenum valueType,
3020*8975f5c5SAndroid Build Coastguard Worker                      UniformLocation location,
3021*8975f5c5SAndroid Build Coastguard Worker                      GLsizei count)
3022*8975f5c5SAndroid Build Coastguard Worker {
3023*8975f5c5SAndroid Build Coastguard Worker     const LinkedUniform *uniform = nullptr;
3024*8975f5c5SAndroid Build Coastguard Worker     Program *programObject       = context->getActiveLinkedProgram();
3025*8975f5c5SAndroid Build Coastguard Worker     return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
3026*8975f5c5SAndroid Build Coastguard Worker                                      &uniform) &&
3027*8975f5c5SAndroid Build Coastguard Worker            ValidateUniformValue(context, entryPoint, valueType, uniform->getType());
3028*8975f5c5SAndroid Build Coastguard Worker }
3029*8975f5c5SAndroid Build Coastguard Worker 
ValidateUniform1iv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLint * value)3030*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniform1iv(const Context *context,
3031*8975f5c5SAndroid Build Coastguard Worker                         angle::EntryPoint entryPoint,
3032*8975f5c5SAndroid Build Coastguard Worker                         UniformLocation location,
3033*8975f5c5SAndroid Build Coastguard Worker                         GLsizei count,
3034*8975f5c5SAndroid Build Coastguard Worker                         const GLint *value)
3035*8975f5c5SAndroid Build Coastguard Worker {
3036*8975f5c5SAndroid Build Coastguard Worker     const LinkedUniform *uniform = nullptr;
3037*8975f5c5SAndroid Build Coastguard Worker     Program *programObject       = context->getActiveLinkedProgram();
3038*8975f5c5SAndroid Build Coastguard Worker     return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
3039*8975f5c5SAndroid Build Coastguard Worker                                      &uniform) &&
3040*8975f5c5SAndroid Build Coastguard Worker            ValidateUniform1ivValue(context, entryPoint, uniform->getType(), count, value);
3041*8975f5c5SAndroid Build Coastguard Worker }
3042*8975f5c5SAndroid Build Coastguard Worker 
ValidateUniformMatrix(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,UniformLocation location,GLsizei count,GLboolean transpose)3043*8975f5c5SAndroid Build Coastguard Worker bool ValidateUniformMatrix(const Context *context,
3044*8975f5c5SAndroid Build Coastguard Worker                            angle::EntryPoint entryPoint,
3045*8975f5c5SAndroid Build Coastguard Worker                            GLenum valueType,
3046*8975f5c5SAndroid Build Coastguard Worker                            UniformLocation location,
3047*8975f5c5SAndroid Build Coastguard Worker                            GLsizei count,
3048*8975f5c5SAndroid Build Coastguard Worker                            GLboolean transpose)
3049*8975f5c5SAndroid Build Coastguard Worker {
3050*8975f5c5SAndroid Build Coastguard Worker     if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
3051*8975f5c5SAndroid Build Coastguard Worker     {
3052*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kES3Required);
3053*8975f5c5SAndroid Build Coastguard Worker         return false;
3054*8975f5c5SAndroid Build Coastguard Worker     }
3055*8975f5c5SAndroid Build Coastguard Worker 
3056*8975f5c5SAndroid Build Coastguard Worker     const LinkedUniform *uniform = nullptr;
3057*8975f5c5SAndroid Build Coastguard Worker     Program *programObject       = context->getActiveLinkedProgram();
3058*8975f5c5SAndroid Build Coastguard Worker     return ValidateUniformCommonBase(context, entryPoint, programObject, location, count,
3059*8975f5c5SAndroid Build Coastguard Worker                                      &uniform) &&
3060*8975f5c5SAndroid Build Coastguard Worker            ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->getType());
3061*8975f5c5SAndroid Build Coastguard Worker }
3062*8975f5c5SAndroid Build Coastguard Worker 
ValidateStateQuery(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLenum * nativeType,unsigned int * numParams)3063*8975f5c5SAndroid Build Coastguard Worker bool ValidateStateQuery(const Context *context,
3064*8975f5c5SAndroid Build Coastguard Worker                         angle::EntryPoint entryPoint,
3065*8975f5c5SAndroid Build Coastguard Worker                         GLenum pname,
3066*8975f5c5SAndroid Build Coastguard Worker                         GLenum *nativeType,
3067*8975f5c5SAndroid Build Coastguard Worker                         unsigned int *numParams)
3068*8975f5c5SAndroid Build Coastguard Worker {
3069*8975f5c5SAndroid Build Coastguard Worker     if (!context->getQueryParameterInfo(pname, nativeType, numParams))
3070*8975f5c5SAndroid Build Coastguard Worker     {
3071*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
3072*8975f5c5SAndroid Build Coastguard Worker         return false;
3073*8975f5c5SAndroid Build Coastguard Worker     }
3074*8975f5c5SAndroid Build Coastguard Worker 
3075*8975f5c5SAndroid Build Coastguard Worker     const Caps &caps = context->getCaps();
3076*8975f5c5SAndroid Build Coastguard Worker 
3077*8975f5c5SAndroid Build Coastguard Worker     if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
3078*8975f5c5SAndroid Build Coastguard Worker     {
3079*8975f5c5SAndroid Build Coastguard Worker         int colorAttachment = (pname - GL_DRAW_BUFFER0);
3080*8975f5c5SAndroid Build Coastguard Worker 
3081*8975f5c5SAndroid Build Coastguard Worker         if (colorAttachment >= caps.maxDrawBuffers)
3082*8975f5c5SAndroid Build Coastguard Worker         {
3083*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
3084*8975f5c5SAndroid Build Coastguard Worker             return false;
3085*8975f5c5SAndroid Build Coastguard Worker         }
3086*8975f5c5SAndroid Build Coastguard Worker     }
3087*8975f5c5SAndroid Build Coastguard Worker 
3088*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
3089*8975f5c5SAndroid Build Coastguard Worker     {
3090*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_2D:
3091*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_CUBE_MAP:
3092*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_3D:
3093*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_2D_ARRAY:
3094*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
3095*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
3096*8975f5c5SAndroid Build Coastguard Worker             break;
3097*8975f5c5SAndroid Build Coastguard Worker 
3098*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
3099*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureRectangleANGLE)
3100*8975f5c5SAndroid Build Coastguard Worker             {
3101*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3102*8975f5c5SAndroid Build Coastguard Worker                 return false;
3103*8975f5c5SAndroid Build Coastguard Worker             }
3104*8975f5c5SAndroid Build Coastguard Worker             break;
3105*8975f5c5SAndroid Build Coastguard Worker 
3106*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_EXTERNAL_OES:
3107*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().EGLStreamConsumerExternalNV &&
3108*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().EGLImageExternalOES)
3109*8975f5c5SAndroid Build Coastguard Worker             {
3110*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3111*8975f5c5SAndroid Build Coastguard Worker                 return false;
3112*8975f5c5SAndroid Build Coastguard Worker             }
3113*8975f5c5SAndroid Build Coastguard Worker             break;
3114*8975f5c5SAndroid Build Coastguard Worker 
3115*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BUFFER_BINDING:
3116*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BINDING_BUFFER:
3117*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
3118*8975f5c5SAndroid Build Coastguard Worker         case GL_MAX_TEXTURE_BUFFER_SIZE:
3119*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 2) &&
3120*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().textureBufferAny())
3121*8975f5c5SAndroid Build Coastguard Worker             {
3122*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferExtensionNotAvailable);
3123*8975f5c5SAndroid Build Coastguard Worker                 return false;
3124*8975f5c5SAndroid Build Coastguard Worker             }
3125*8975f5c5SAndroid Build Coastguard Worker             break;
3126*8975f5c5SAndroid Build Coastguard Worker 
3127*8975f5c5SAndroid Build Coastguard Worker         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3128*8975f5c5SAndroid Build Coastguard Worker         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3129*8975f5c5SAndroid Build Coastguard Worker         {
3130*8975f5c5SAndroid Build Coastguard Worker             Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
3131*8975f5c5SAndroid Build Coastguard Worker             ASSERT(readFramebuffer);
3132*8975f5c5SAndroid Build Coastguard Worker 
3133*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, entryPoint,
3134*8975f5c5SAndroid Build Coastguard Worker                                                                    readFramebuffer))
3135*8975f5c5SAndroid Build Coastguard Worker             {
3136*8975f5c5SAndroid Build Coastguard Worker                 return false;
3137*8975f5c5SAndroid Build Coastguard Worker             }
3138*8975f5c5SAndroid Build Coastguard Worker 
3139*8975f5c5SAndroid Build Coastguard Worker             if (readFramebuffer->getReadBufferState() == GL_NONE)
3140*8975f5c5SAndroid Build Coastguard Worker             {
3141*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNone);
3142*8975f5c5SAndroid Build Coastguard Worker                 return false;
3143*8975f5c5SAndroid Build Coastguard Worker             }
3144*8975f5c5SAndroid Build Coastguard Worker 
3145*8975f5c5SAndroid Build Coastguard Worker             const FramebufferAttachment *attachment = readFramebuffer->getReadColorAttachment();
3146*8975f5c5SAndroid Build Coastguard Worker             if (!attachment)
3147*8975f5c5SAndroid Build Coastguard Worker             {
3148*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNotAttached);
3149*8975f5c5SAndroid Build Coastguard Worker                 return false;
3150*8975f5c5SAndroid Build Coastguard Worker             }
3151*8975f5c5SAndroid Build Coastguard Worker             break;
3152*8975f5c5SAndroid Build Coastguard Worker         }
3153*8975f5c5SAndroid Build Coastguard Worker 
3154*8975f5c5SAndroid Build Coastguard Worker         case GL_PRIMITIVE_BOUNDING_BOX:
3155*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().primitiveBoundingBoxAny())
3156*8975f5c5SAndroid Build Coastguard Worker             {
3157*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
3158*8975f5c5SAndroid Build Coastguard Worker                 return false;
3159*8975f5c5SAndroid Build Coastguard Worker             }
3160*8975f5c5SAndroid Build Coastguard Worker             break;
3161*8975f5c5SAndroid Build Coastguard Worker 
3162*8975f5c5SAndroid Build Coastguard Worker         case GL_SHADING_RATE_QCOM:
3163*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().shadingRateQCOM)
3164*8975f5c5SAndroid Build Coastguard Worker             {
3165*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
3166*8975f5c5SAndroid Build Coastguard Worker                 return false;
3167*8975f5c5SAndroid Build Coastguard Worker             }
3168*8975f5c5SAndroid Build Coastguard Worker             break;
3169*8975f5c5SAndroid Build Coastguard Worker 
3170*8975f5c5SAndroid Build Coastguard Worker         case GL_MULTISAMPLE_LINE_WIDTH_RANGE:
3171*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 2))
3172*8975f5c5SAndroid Build Coastguard Worker             {
3173*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3174*8975f5c5SAndroid Build Coastguard Worker                 return false;
3175*8975f5c5SAndroid Build Coastguard Worker             }
3176*8975f5c5SAndroid Build Coastguard Worker             break;
3177*8975f5c5SAndroid Build Coastguard Worker 
3178*8975f5c5SAndroid Build Coastguard Worker         case GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY:
3179*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 2))
3180*8975f5c5SAndroid Build Coastguard Worker             {
3181*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3182*8975f5c5SAndroid Build Coastguard Worker                 return false;
3183*8975f5c5SAndroid Build Coastguard Worker             }
3184*8975f5c5SAndroid Build Coastguard Worker             break;
3185*8975f5c5SAndroid Build Coastguard Worker 
3186*8975f5c5SAndroid Build Coastguard Worker         case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
3187*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 2) &&
3188*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().tessellationShaderAny())
3189*8975f5c5SAndroid Build Coastguard Worker             {
3190*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
3191*8975f5c5SAndroid Build Coastguard Worker                 return false;
3192*8975f5c5SAndroid Build Coastguard Worker             }
3193*8975f5c5SAndroid Build Coastguard Worker             break;
3194*8975f5c5SAndroid Build Coastguard Worker 
3195*8975f5c5SAndroid Build Coastguard Worker         default:
3196*8975f5c5SAndroid Build Coastguard Worker             break;
3197*8975f5c5SAndroid Build Coastguard Worker     }
3198*8975f5c5SAndroid Build Coastguard Worker 
3199*8975f5c5SAndroid Build Coastguard Worker     // pname is valid, but there are no parameters to return
3200*8975f5c5SAndroid Build Coastguard Worker     if (*numParams == 0)
3201*8975f5c5SAndroid Build Coastguard Worker     {
3202*8975f5c5SAndroid Build Coastguard Worker         return false;
3203*8975f5c5SAndroid Build Coastguard Worker     }
3204*8975f5c5SAndroid Build Coastguard Worker 
3205*8975f5c5SAndroid Build Coastguard Worker     return true;
3206*8975f5c5SAndroid Build Coastguard Worker }
3207*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetBooleanvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLboolean * params)3208*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBooleanvRobustANGLE(const Context *context,
3209*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
3210*8975f5c5SAndroid Build Coastguard Worker                                     GLenum pname,
3211*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei bufSize,
3212*8975f5c5SAndroid Build Coastguard Worker                                     const GLsizei *length,
3213*8975f5c5SAndroid Build Coastguard Worker                                     const GLboolean *params)
3214*8975f5c5SAndroid Build Coastguard Worker {
3215*8975f5c5SAndroid Build Coastguard Worker     GLenum nativeType;
3216*8975f5c5SAndroid Build Coastguard Worker     unsigned int numParams = 0;
3217*8975f5c5SAndroid Build Coastguard Worker 
3218*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3219*8975f5c5SAndroid Build Coastguard Worker     {
3220*8975f5c5SAndroid Build Coastguard Worker         return false;
3221*8975f5c5SAndroid Build Coastguard Worker     }
3222*8975f5c5SAndroid Build Coastguard Worker 
3223*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
3224*8975f5c5SAndroid Build Coastguard Worker 
3225*8975f5c5SAndroid Build Coastguard Worker     return true;
3226*8975f5c5SAndroid Build Coastguard Worker }
3227*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetFloatvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)3228*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFloatvRobustANGLE(const Context *context,
3229*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
3230*8975f5c5SAndroid Build Coastguard Worker                                   GLenum pname,
3231*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei bufSize,
3232*8975f5c5SAndroid Build Coastguard Worker                                   const GLsizei *length,
3233*8975f5c5SAndroid Build Coastguard Worker                                   const GLfloat *params)
3234*8975f5c5SAndroid Build Coastguard Worker {
3235*8975f5c5SAndroid Build Coastguard Worker     GLenum nativeType;
3236*8975f5c5SAndroid Build Coastguard Worker     unsigned int numParams = 0;
3237*8975f5c5SAndroid Build Coastguard Worker 
3238*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3239*8975f5c5SAndroid Build Coastguard Worker     {
3240*8975f5c5SAndroid Build Coastguard Worker         return false;
3241*8975f5c5SAndroid Build Coastguard Worker     }
3242*8975f5c5SAndroid Build Coastguard Worker 
3243*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
3244*8975f5c5SAndroid Build Coastguard Worker 
3245*8975f5c5SAndroid Build Coastguard Worker     return true;
3246*8975f5c5SAndroid Build Coastguard Worker }
3247*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetIntegervRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * data)3248*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetIntegervRobustANGLE(const Context *context,
3249*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
3250*8975f5c5SAndroid Build Coastguard Worker                                     GLenum pname,
3251*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei bufSize,
3252*8975f5c5SAndroid Build Coastguard Worker                                     const GLsizei *length,
3253*8975f5c5SAndroid Build Coastguard Worker                                     const GLint *data)
3254*8975f5c5SAndroid Build Coastguard Worker {
3255*8975f5c5SAndroid Build Coastguard Worker     GLenum nativeType;
3256*8975f5c5SAndroid Build Coastguard Worker     unsigned int numParams = 0;
3257*8975f5c5SAndroid Build Coastguard Worker 
3258*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3259*8975f5c5SAndroid Build Coastguard Worker     {
3260*8975f5c5SAndroid Build Coastguard Worker         return false;
3261*8975f5c5SAndroid Build Coastguard Worker     }
3262*8975f5c5SAndroid Build Coastguard Worker 
3263*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
3264*8975f5c5SAndroid Build Coastguard Worker 
3265*8975f5c5SAndroid Build Coastguard Worker     return true;
3266*8975f5c5SAndroid Build Coastguard Worker }
3267*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetInteger64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,GLint64 * data)3268*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetInteger64vRobustANGLE(const Context *context,
3269*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
3270*8975f5c5SAndroid Build Coastguard Worker                                       GLenum pname,
3271*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei bufSize,
3272*8975f5c5SAndroid Build Coastguard Worker                                       const GLsizei *length,
3273*8975f5c5SAndroid Build Coastguard Worker                                       GLint64 *data)
3274*8975f5c5SAndroid Build Coastguard Worker {
3275*8975f5c5SAndroid Build Coastguard Worker     GLenum nativeType;
3276*8975f5c5SAndroid Build Coastguard Worker     unsigned int numParams = 0;
3277*8975f5c5SAndroid Build Coastguard Worker 
3278*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustStateQuery(context, entryPoint, pname, bufSize, &nativeType, &numParams))
3279*8975f5c5SAndroid Build Coastguard Worker     {
3280*8975f5c5SAndroid Build Coastguard Worker         return false;
3281*8975f5c5SAndroid Build Coastguard Worker     }
3282*8975f5c5SAndroid Build Coastguard Worker 
3283*8975f5c5SAndroid Build Coastguard Worker     if (nativeType == GL_INT_64_ANGLEX)
3284*8975f5c5SAndroid Build Coastguard Worker     {
3285*8975f5c5SAndroid Build Coastguard Worker         CastStateValues(context, nativeType, pname, numParams, data);
3286*8975f5c5SAndroid Build Coastguard Worker         return false;
3287*8975f5c5SAndroid Build Coastguard Worker     }
3288*8975f5c5SAndroid Build Coastguard Worker 
3289*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
3290*8975f5c5SAndroid Build Coastguard Worker     return true;
3291*8975f5c5SAndroid Build Coastguard Worker }
3292*8975f5c5SAndroid Build Coastguard Worker 
ValidateRobustStateQuery(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,GLenum * nativeType,unsigned int * numParams)3293*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustStateQuery(const Context *context,
3294*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
3295*8975f5c5SAndroid Build Coastguard Worker                               GLenum pname,
3296*8975f5c5SAndroid Build Coastguard Worker                               GLsizei bufSize,
3297*8975f5c5SAndroid Build Coastguard Worker                               GLenum *nativeType,
3298*8975f5c5SAndroid Build Coastguard Worker                               unsigned int *numParams)
3299*8975f5c5SAndroid Build Coastguard Worker {
3300*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
3301*8975f5c5SAndroid Build Coastguard Worker     {
3302*8975f5c5SAndroid Build Coastguard Worker         return false;
3303*8975f5c5SAndroid Build Coastguard Worker     }
3304*8975f5c5SAndroid Build Coastguard Worker 
3305*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateStateQuery(context, entryPoint, pname, nativeType, numParams))
3306*8975f5c5SAndroid Build Coastguard Worker     {
3307*8975f5c5SAndroid Build Coastguard Worker         return false;
3308*8975f5c5SAndroid Build Coastguard Worker     }
3309*8975f5c5SAndroid Build Coastguard Worker 
3310*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, *numParams))
3311*8975f5c5SAndroid Build Coastguard Worker     {
3312*8975f5c5SAndroid Build Coastguard Worker         return false;
3313*8975f5c5SAndroid Build Coastguard Worker     }
3314*8975f5c5SAndroid Build Coastguard Worker 
3315*8975f5c5SAndroid Build Coastguard Worker     return true;
3316*8975f5c5SAndroid Build Coastguard Worker }
3317*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyImageSubDataTarget(const Context * context,angle::EntryPoint entryPoint,GLuint name,GLenum target)3318*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataTarget(const Context *context,
3319*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
3320*8975f5c5SAndroid Build Coastguard Worker                                     GLuint name,
3321*8975f5c5SAndroid Build Coastguard Worker                                     GLenum target)
3322*8975f5c5SAndroid Build Coastguard Worker {
3323*8975f5c5SAndroid Build Coastguard Worker     // From EXT_copy_image: INVALID_ENUM is generated if either <srcTarget> or <dstTarget> is not
3324*8975f5c5SAndroid Build Coastguard Worker     // RENDERBUFFER or a valid non - proxy texture target, is TEXTURE_BUFFER, or is one of the
3325*8975f5c5SAndroid Build Coastguard Worker     // cubemap face selectors described in table 3.17, or if the target does not match the type of
3326*8975f5c5SAndroid Build Coastguard Worker     // the object. INVALID_VALUE is generated if either <srcName> or <dstName> does not correspond
3327*8975f5c5SAndroid Build Coastguard Worker     // to a valid renderbuffer or texture object according to the corresponding target parameter.
3328*8975f5c5SAndroid Build Coastguard Worker     switch (target)
3329*8975f5c5SAndroid Build Coastguard Worker     {
3330*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER:
3331*8975f5c5SAndroid Build Coastguard Worker         {
3332*8975f5c5SAndroid Build Coastguard Worker             RenderbufferID renderbuffer = PackParam<RenderbufferID>(name);
3333*8975f5c5SAndroid Build Coastguard Worker             if (!context->isRenderbuffer(renderbuffer))
3334*8975f5c5SAndroid Build Coastguard Worker             {
3335*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidRenderbufferName);
3336*8975f5c5SAndroid Build Coastguard Worker                 return false;
3337*8975f5c5SAndroid Build Coastguard Worker             }
3338*8975f5c5SAndroid Build Coastguard Worker             break;
3339*8975f5c5SAndroid Build Coastguard Worker         }
3340*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D:
3341*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_3D:
3342*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D_ARRAY:
3343*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP:
3344*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
3345*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_EXTERNAL_OES:
3346*8975f5c5SAndroid Build Coastguard Worker         {
3347*8975f5c5SAndroid Build Coastguard Worker             TextureID texture = PackParam<TextureID>(name);
3348*8975f5c5SAndroid Build Coastguard Worker             if (!context->isTexture(texture))
3349*8975f5c5SAndroid Build Coastguard Worker             {
3350*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
3351*8975f5c5SAndroid Build Coastguard Worker                 return false;
3352*8975f5c5SAndroid Build Coastguard Worker             }
3353*8975f5c5SAndroid Build Coastguard Worker 
3354*8975f5c5SAndroid Build Coastguard Worker             Texture *textureObject = context->getTexture(texture);
3355*8975f5c5SAndroid Build Coastguard Worker             if (textureObject && textureObject->getType() != PackParam<TextureType>(target))
3356*8975f5c5SAndroid Build Coastguard Worker             {
3357*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kTextureTypeMismatch);
3358*8975f5c5SAndroid Build Coastguard Worker                 return false;
3359*8975f5c5SAndroid Build Coastguard Worker             }
3360*8975f5c5SAndroid Build Coastguard Worker             break;
3361*8975f5c5SAndroid Build Coastguard Worker         }
3362*8975f5c5SAndroid Build Coastguard Worker         default:
3363*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
3364*8975f5c5SAndroid Build Coastguard Worker             return false;
3365*8975f5c5SAndroid Build Coastguard Worker     }
3366*8975f5c5SAndroid Build Coastguard Worker 
3367*8975f5c5SAndroid Build Coastguard Worker     return true;
3368*8975f5c5SAndroid Build Coastguard Worker }
3369*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyImageSubDataLevel(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLint level)3370*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataLevel(const Context *context,
3371*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
3372*8975f5c5SAndroid Build Coastguard Worker                                    GLenum target,
3373*8975f5c5SAndroid Build Coastguard Worker                                    GLint level)
3374*8975f5c5SAndroid Build Coastguard Worker {
3375*8975f5c5SAndroid Build Coastguard Worker     switch (target)
3376*8975f5c5SAndroid Build Coastguard Worker     {
3377*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER:
3378*8975f5c5SAndroid Build Coastguard Worker         {
3379*8975f5c5SAndroid Build Coastguard Worker             if (level != 0)
3380*8975f5c5SAndroid Build Coastguard Worker             {
3381*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3382*8975f5c5SAndroid Build Coastguard Worker                 return false;
3383*8975f5c5SAndroid Build Coastguard Worker             }
3384*8975f5c5SAndroid Build Coastguard Worker             break;
3385*8975f5c5SAndroid Build Coastguard Worker         }
3386*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D:
3387*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_3D:
3388*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D_ARRAY:
3389*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP:
3390*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
3391*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_EXTERNAL_OES:
3392*8975f5c5SAndroid Build Coastguard Worker         {
3393*8975f5c5SAndroid Build Coastguard Worker             if (!ValidMipLevel(context, PackParam<TextureType>(target), level))
3394*8975f5c5SAndroid Build Coastguard Worker             {
3395*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3396*8975f5c5SAndroid Build Coastguard Worker                 return false;
3397*8975f5c5SAndroid Build Coastguard Worker             }
3398*8975f5c5SAndroid Build Coastguard Worker             break;
3399*8975f5c5SAndroid Build Coastguard Worker         }
3400*8975f5c5SAndroid Build Coastguard Worker         default:
3401*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
3402*8975f5c5SAndroid Build Coastguard Worker             return false;
3403*8975f5c5SAndroid Build Coastguard Worker     }
3404*8975f5c5SAndroid Build Coastguard Worker 
3405*8975f5c5SAndroid Build Coastguard Worker     return true;
3406*8975f5c5SAndroid Build Coastguard Worker }
3407*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyImageSubDataTargetRegion(const Context * context,angle::EntryPoint entryPoint,GLuint name,GLenum target,GLint level,GLint offsetX,GLint offsetY,GLint offsetZ,GLsizei width,GLsizei height,GLsizei * samples)3408*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataTargetRegion(const Context *context,
3409*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
3410*8975f5c5SAndroid Build Coastguard Worker                                           GLuint name,
3411*8975f5c5SAndroid Build Coastguard Worker                                           GLenum target,
3412*8975f5c5SAndroid Build Coastguard Worker                                           GLint level,
3413*8975f5c5SAndroid Build Coastguard Worker                                           GLint offsetX,
3414*8975f5c5SAndroid Build Coastguard Worker                                           GLint offsetY,
3415*8975f5c5SAndroid Build Coastguard Worker                                           GLint offsetZ,
3416*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei width,
3417*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei height,
3418*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei *samples)
3419*8975f5c5SAndroid Build Coastguard Worker {
3420*8975f5c5SAndroid Build Coastguard Worker     // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries
3421*8975f5c5SAndroid Build Coastguard Worker     // of the corresponding image object.
3422*8975f5c5SAndroid Build Coastguard Worker     if (offsetX < 0 || offsetY < 0 || offsetZ < 0)
3423*8975f5c5SAndroid Build Coastguard Worker     {
3424*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3425*8975f5c5SAndroid Build Coastguard Worker         return false;
3426*8975f5c5SAndroid Build Coastguard Worker     }
3427*8975f5c5SAndroid Build Coastguard Worker 
3428*8975f5c5SAndroid Build Coastguard Worker     if (target == GL_RENDERBUFFER)
3429*8975f5c5SAndroid Build Coastguard Worker     {
3430*8975f5c5SAndroid Build Coastguard Worker         // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the
3431*8975f5c5SAndroid Build Coastguard Worker         // boundaries of the corresponding image object
3432*8975f5c5SAndroid Build Coastguard Worker         Renderbuffer *buffer = context->getRenderbuffer(PackParam<RenderbufferID>(name));
3433*8975f5c5SAndroid Build Coastguard Worker         if ((buffer->getWidth() - offsetX < width) || (buffer->getHeight() - offsetY < height))
3434*8975f5c5SAndroid Build Coastguard Worker         {
3435*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureTooSmall);
3436*8975f5c5SAndroid Build Coastguard Worker             return false;
3437*8975f5c5SAndroid Build Coastguard Worker         }
3438*8975f5c5SAndroid Build Coastguard Worker     }
3439*8975f5c5SAndroid Build Coastguard Worker     else
3440*8975f5c5SAndroid Build Coastguard Worker     {
3441*8975f5c5SAndroid Build Coastguard Worker         Texture *texture = context->getTexture(PackParam<TextureID>(name));
3442*8975f5c5SAndroid Build Coastguard Worker 
3443*8975f5c5SAndroid Build Coastguard Worker         // INVALID_OPERATION is generated if either object is a texture and the texture is not
3444*8975f5c5SAndroid Build Coastguard Worker         // complete
3445*8975f5c5SAndroid Build Coastguard Worker         // This will handle the texture completeness check. Note that this ignores format-based
3446*8975f5c5SAndroid Build Coastguard Worker         // compleness rules.
3447*8975f5c5SAndroid Build Coastguard Worker         if (!texture->isSamplerCompleteForCopyImage(context, nullptr))
3448*8975f5c5SAndroid Build Coastguard Worker         {
3449*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNotTextureComplete);
3450*8975f5c5SAndroid Build Coastguard Worker             return false;
3451*8975f5c5SAndroid Build Coastguard Worker         }
3452*8975f5c5SAndroid Build Coastguard Worker 
3453*8975f5c5SAndroid Build Coastguard Worker         GLenum textureTargetToUse = target;
3454*8975f5c5SAndroid Build Coastguard Worker         if (target == GL_TEXTURE_CUBE_MAP)
3455*8975f5c5SAndroid Build Coastguard Worker         {
3456*8975f5c5SAndroid Build Coastguard Worker             // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the textureWidth/textureHeight
3457*8975f5c5SAndroid Build Coastguard Worker             textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
3458*8975f5c5SAndroid Build Coastguard Worker         }
3459*8975f5c5SAndroid Build Coastguard Worker 
3460*8975f5c5SAndroid Build Coastguard Worker         const GLsizei textureWidth = static_cast<GLsizei>(
3461*8975f5c5SAndroid Build Coastguard Worker             texture->getWidth(PackParam<TextureTarget>(textureTargetToUse), level));
3462*8975f5c5SAndroid Build Coastguard Worker         const GLsizei textureHeight = static_cast<GLsizei>(
3463*8975f5c5SAndroid Build Coastguard Worker             texture->getHeight(PackParam<TextureTarget>(textureTargetToUse), level));
3464*8975f5c5SAndroid Build Coastguard Worker 
3465*8975f5c5SAndroid Build Coastguard Worker         // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the
3466*8975f5c5SAndroid Build Coastguard Worker         // boundaries of the corresponding image object
3467*8975f5c5SAndroid Build Coastguard Worker         if ((textureWidth - offsetX < width) || (textureHeight - offsetY < height))
3468*8975f5c5SAndroid Build Coastguard Worker         {
3469*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureTooSmall);
3470*8975f5c5SAndroid Build Coastguard Worker             return false;
3471*8975f5c5SAndroid Build Coastguard Worker         }
3472*8975f5c5SAndroid Build Coastguard Worker 
3473*8975f5c5SAndroid Build Coastguard Worker         *samples = texture->getSamples(PackParam<TextureTarget>(textureTargetToUse), level);
3474*8975f5c5SAndroid Build Coastguard Worker         *samples = (*samples == 0) ? 1 : *samples;
3475*8975f5c5SAndroid Build Coastguard Worker     }
3476*8975f5c5SAndroid Build Coastguard Worker 
3477*8975f5c5SAndroid Build Coastguard Worker     return true;
3478*8975f5c5SAndroid Build Coastguard Worker }
3479*8975f5c5SAndroid Build Coastguard Worker 
ValidateCompressedRegion(const Context * context,angle::EntryPoint entryPoint,const InternalFormat & formatInfo,GLsizei width,GLsizei height)3480*8975f5c5SAndroid Build Coastguard Worker bool ValidateCompressedRegion(const Context *context,
3481*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
3482*8975f5c5SAndroid Build Coastguard Worker                               const InternalFormat &formatInfo,
3483*8975f5c5SAndroid Build Coastguard Worker                               GLsizei width,
3484*8975f5c5SAndroid Build Coastguard Worker                               GLsizei height)
3485*8975f5c5SAndroid Build Coastguard Worker {
3486*8975f5c5SAndroid Build Coastguard Worker     ASSERT(formatInfo.compressed);
3487*8975f5c5SAndroid Build Coastguard Worker 
3488*8975f5c5SAndroid Build Coastguard Worker     // INVALID_VALUE is generated if the image format is compressed and the dimensions of the
3489*8975f5c5SAndroid Build Coastguard Worker     // subregion fail to meet the alignment constraints of the format.
3490*8975f5c5SAndroid Build Coastguard Worker     if ((width % formatInfo.compressedBlockWidth != 0) ||
3491*8975f5c5SAndroid Build Coastguard Worker         (height % formatInfo.compressedBlockHeight != 0))
3492*8975f5c5SAndroid Build Coastguard Worker     {
3493*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidCompressedRegionSize);
3494*8975f5c5SAndroid Build Coastguard Worker         return false;
3495*8975f5c5SAndroid Build Coastguard Worker     }
3496*8975f5c5SAndroid Build Coastguard Worker 
3497*8975f5c5SAndroid Build Coastguard Worker     return true;
3498*8975f5c5SAndroid Build Coastguard Worker }
3499*8975f5c5SAndroid Build Coastguard Worker 
GetTargetFormatInfo(const Context * context,angle::EntryPoint entryPoint,GLuint name,GLenum target,GLint level)3500*8975f5c5SAndroid Build Coastguard Worker const InternalFormat &GetTargetFormatInfo(const Context *context,
3501*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
3502*8975f5c5SAndroid Build Coastguard Worker                                           GLuint name,
3503*8975f5c5SAndroid Build Coastguard Worker                                           GLenum target,
3504*8975f5c5SAndroid Build Coastguard Worker                                           GLint level)
3505*8975f5c5SAndroid Build Coastguard Worker {
3506*8975f5c5SAndroid Build Coastguard Worker     static const InternalFormat defaultInternalFormat;
3507*8975f5c5SAndroid Build Coastguard Worker 
3508*8975f5c5SAndroid Build Coastguard Worker     switch (target)
3509*8975f5c5SAndroid Build Coastguard Worker     {
3510*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER:
3511*8975f5c5SAndroid Build Coastguard Worker         {
3512*8975f5c5SAndroid Build Coastguard Worker             Renderbuffer *buffer = context->getRenderbuffer(PackParam<RenderbufferID>(name));
3513*8975f5c5SAndroid Build Coastguard Worker             return *buffer->getFormat().info;
3514*8975f5c5SAndroid Build Coastguard Worker         }
3515*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D:
3516*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_3D:
3517*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D_ARRAY:
3518*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP:
3519*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP_ARRAY_EXT:
3520*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_EXTERNAL_OES:
3521*8975f5c5SAndroid Build Coastguard Worker         {
3522*8975f5c5SAndroid Build Coastguard Worker             Texture *texture          = context->getTexture(PackParam<TextureID>(name));
3523*8975f5c5SAndroid Build Coastguard Worker             GLenum textureTargetToUse = target;
3524*8975f5c5SAndroid Build Coastguard Worker 
3525*8975f5c5SAndroid Build Coastguard Worker             if (target == GL_TEXTURE_CUBE_MAP)
3526*8975f5c5SAndroid Build Coastguard Worker             {
3527*8975f5c5SAndroid Build Coastguard Worker                 // Use GL_TEXTURE_CUBE_MAP_POSITIVE_X to properly gather the
3528*8975f5c5SAndroid Build Coastguard Worker                 // textureWidth/textureHeight
3529*8975f5c5SAndroid Build Coastguard Worker                 textureTargetToUse = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
3530*8975f5c5SAndroid Build Coastguard Worker             }
3531*8975f5c5SAndroid Build Coastguard Worker             return *texture->getFormat(PackParam<TextureTarget>(textureTargetToUse), level).info;
3532*8975f5c5SAndroid Build Coastguard Worker         }
3533*8975f5c5SAndroid Build Coastguard Worker         default:
3534*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
3535*8975f5c5SAndroid Build Coastguard Worker             return defaultInternalFormat;
3536*8975f5c5SAndroid Build Coastguard Worker     }
3537*8975f5c5SAndroid Build Coastguard Worker }
3538*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyMixedFormatCompatible(GLenum uncompressedFormat,GLenum compressedFormat)3539*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyMixedFormatCompatible(GLenum uncompressedFormat, GLenum compressedFormat)
3540*8975f5c5SAndroid Build Coastguard Worker {
3541*8975f5c5SAndroid Build Coastguard Worker     // Validates mixed format compatibility (uncompressed and compressed) from Table 4.X.1 of the
3542*8975f5c5SAndroid Build Coastguard Worker     // EXT_copy_image spec.
3543*8975f5c5SAndroid Build Coastguard Worker     switch (compressedFormat)
3544*8975f5c5SAndroid Build Coastguard Worker     {
3545*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
3546*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
3547*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
3548*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
3549*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
3550*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
3551*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
3552*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
3553*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
3554*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
3555*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA8_ETC2_EAC:
3556*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
3557*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RG11_EAC:
3558*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RG11_EAC:
3559*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
3560*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
3561*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
3562*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
3563*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
3564*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
3565*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
3566*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
3567*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
3568*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
3569*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
3570*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
3571*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
3572*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
3573*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
3574*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
3575*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
3576*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
3577*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
3578*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
3579*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
3580*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
3581*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
3582*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
3583*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
3584*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
3585*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
3586*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
3587*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
3588*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
3589*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
3590*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
3591*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
3592*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
3593*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
3594*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
3595*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
3596*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
3597*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES:
3598*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES:
3599*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES:
3600*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES:
3601*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES:
3602*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES:
3603*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES:
3604*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES:
3605*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES:
3606*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES:
3607*8975f5c5SAndroid Build Coastguard Worker         {
3608*8975f5c5SAndroid Build Coastguard Worker             switch (uncompressedFormat)
3609*8975f5c5SAndroid Build Coastguard Worker             {
3610*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA32UI:
3611*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA32I:
3612*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA32F:
3613*8975f5c5SAndroid Build Coastguard Worker                     return true;
3614*8975f5c5SAndroid Build Coastguard Worker                 default:
3615*8975f5c5SAndroid Build Coastguard Worker                     return false;
3616*8975f5c5SAndroid Build Coastguard Worker             }
3617*8975f5c5SAndroid Build Coastguard Worker         }
3618*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
3619*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
3620*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
3621*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
3622*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RED_RGTC1_EXT:
3623*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
3624*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB8_ETC2:
3625*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_ETC2:
3626*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_R11_EAC:
3627*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_R11_EAC:
3628*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
3629*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
3630*8975f5c5SAndroid Build Coastguard Worker         {
3631*8975f5c5SAndroid Build Coastguard Worker             switch (uncompressedFormat)
3632*8975f5c5SAndroid Build Coastguard Worker             {
3633*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA16UI:
3634*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA16I:
3635*8975f5c5SAndroid Build Coastguard Worker                 case GL_RGBA16F:
3636*8975f5c5SAndroid Build Coastguard Worker                 case GL_RG32UI:
3637*8975f5c5SAndroid Build Coastguard Worker                 case GL_RG32I:
3638*8975f5c5SAndroid Build Coastguard Worker                 case GL_RG32F:
3639*8975f5c5SAndroid Build Coastguard Worker                     return true;
3640*8975f5c5SAndroid Build Coastguard Worker                 default:
3641*8975f5c5SAndroid Build Coastguard Worker                     return false;
3642*8975f5c5SAndroid Build Coastguard Worker             }
3643*8975f5c5SAndroid Build Coastguard Worker         }
3644*8975f5c5SAndroid Build Coastguard Worker         default:
3645*8975f5c5SAndroid Build Coastguard Worker             break;
3646*8975f5c5SAndroid Build Coastguard Worker     }
3647*8975f5c5SAndroid Build Coastguard Worker 
3648*8975f5c5SAndroid Build Coastguard Worker     return false;
3649*8975f5c5SAndroid Build Coastguard Worker }
3650*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyCompressedFormatCompatible(const InternalFormat & srcFormatInfo,const InternalFormat & dstFormatInfo)3651*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyCompressedFormatCompatible(const InternalFormat &srcFormatInfo,
3652*8975f5c5SAndroid Build Coastguard Worker                                             const InternalFormat &dstFormatInfo)
3653*8975f5c5SAndroid Build Coastguard Worker {
3654*8975f5c5SAndroid Build Coastguard Worker     // Validates compressed format compatibility from Table 4.X.2 of the EXT_copy_image spec.
3655*8975f5c5SAndroid Build Coastguard Worker 
3656*8975f5c5SAndroid Build Coastguard Worker     ASSERT(srcFormatInfo.internalFormat != dstFormatInfo.internalFormat);
3657*8975f5c5SAndroid Build Coastguard Worker 
3658*8975f5c5SAndroid Build Coastguard Worker     const GLenum srcFormat = srcFormatInfo.internalFormat;
3659*8975f5c5SAndroid Build Coastguard Worker     const GLenum dstFormat = dstFormatInfo.internalFormat;
3660*8975f5c5SAndroid Build Coastguard Worker 
3661*8975f5c5SAndroid Build Coastguard Worker     switch (srcFormat)
3662*8975f5c5SAndroid Build Coastguard Worker     {
3663*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RED_RGTC1_EXT:
3664*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_SIGNED_RED_RGTC1_EXT);
3665*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
3666*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_RED_RGTC1_EXT);
3667*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
3668*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT);
3669*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
3670*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT);
3671*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
3672*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT);
3673*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
3674*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT);
3675*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_R11_EAC:
3676*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_SIGNED_R11_EAC);
3677*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_R11_EAC:
3678*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_R11_EAC);
3679*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RG11_EAC:
3680*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_SIGNED_RG11_EAC);
3681*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_SIGNED_RG11_EAC:
3682*8975f5c5SAndroid Build Coastguard Worker             return (dstFormat == GL_COMPRESSED_RG11_EAC);
3683*8975f5c5SAndroid Build Coastguard Worker         default:
3684*8975f5c5SAndroid Build Coastguard Worker             break;
3685*8975f5c5SAndroid Build Coastguard Worker     }
3686*8975f5c5SAndroid Build Coastguard Worker 
3687*8975f5c5SAndroid Build Coastguard Worker     // Since they can't be the same format and are both compressed formats, one must be linear and
3688*8975f5c5SAndroid Build Coastguard Worker     // the other nonlinear.
3689*8975f5c5SAndroid Build Coastguard Worker     if (srcFormatInfo.colorEncoding == dstFormatInfo.colorEncoding)
3690*8975f5c5SAndroid Build Coastguard Worker     {
3691*8975f5c5SAndroid Build Coastguard Worker         return false;
3692*8975f5c5SAndroid Build Coastguard Worker     }
3693*8975f5c5SAndroid Build Coastguard Worker 
3694*8975f5c5SAndroid Build Coastguard Worker     const GLenum linearFormat = (srcFormatInfo.colorEncoding == GL_LINEAR) ? srcFormat : dstFormat;
3695*8975f5c5SAndroid Build Coastguard Worker     const GLenum nonLinearFormat =
3696*8975f5c5SAndroid Build Coastguard Worker         (srcFormatInfo.colorEncoding != GL_LINEAR) ? srcFormat : dstFormat;
3697*8975f5c5SAndroid Build Coastguard Worker 
3698*8975f5c5SAndroid Build Coastguard Worker     switch (linearFormat)
3699*8975f5c5SAndroid Build Coastguard Worker     {
3700*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
3701*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT);
3702*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
3703*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
3704*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
3705*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
3706*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
3707*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
3708*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
3709*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
3710*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB8_ETC2:
3711*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ETC2);
3712*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
3713*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
3714*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA8_ETC2_EAC:
3715*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
3716*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
3717*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR);
3718*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
3719*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR);
3720*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
3721*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR);
3722*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
3723*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR);
3724*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
3725*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR);
3726*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
3727*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR);
3728*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
3729*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR);
3730*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
3731*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR);
3732*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
3733*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR);
3734*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
3735*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR);
3736*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
3737*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR);
3738*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
3739*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR);
3740*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
3741*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR);
3742*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
3743*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR);
3744*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_3x3x3_OES:
3745*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES);
3746*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x3x3_OES:
3747*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES);
3748*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x4x3_OES:
3749*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES);
3750*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_4x4x4_OES:
3751*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES);
3752*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x4x4_OES:
3753*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES);
3754*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x5x4_OES:
3755*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES);
3756*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_5x5x5_OES:
3757*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES);
3758*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x5x5_OES:
3759*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES);
3760*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x6x5_OES:
3761*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES);
3762*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPRESSED_RGBA_ASTC_6x6x6_OES:
3763*8975f5c5SAndroid Build Coastguard Worker             return (nonLinearFormat == GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES);
3764*8975f5c5SAndroid Build Coastguard Worker         default:
3765*8975f5c5SAndroid Build Coastguard Worker             break;
3766*8975f5c5SAndroid Build Coastguard Worker     }
3767*8975f5c5SAndroid Build Coastguard Worker 
3768*8975f5c5SAndroid Build Coastguard Worker     return false;
3769*8975f5c5SAndroid Build Coastguard Worker }
3770*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyFormatCompatible(const InternalFormat & srcFormatInfo,const InternalFormat & dstFormatInfo)3771*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyFormatCompatible(const InternalFormat &srcFormatInfo,
3772*8975f5c5SAndroid Build Coastguard Worker                                   const InternalFormat &dstFormatInfo)
3773*8975f5c5SAndroid Build Coastguard Worker {
3774*8975f5c5SAndroid Build Coastguard Worker     // Matching source and destination formats are compatible.
3775*8975f5c5SAndroid Build Coastguard Worker     if (srcFormatInfo.internalFormat == dstFormatInfo.internalFormat)
3776*8975f5c5SAndroid Build Coastguard Worker     {
3777*8975f5c5SAndroid Build Coastguard Worker         return true;
3778*8975f5c5SAndroid Build Coastguard Worker     }
3779*8975f5c5SAndroid Build Coastguard Worker 
3780*8975f5c5SAndroid Build Coastguard Worker     if (srcFormatInfo.compressed != dstFormatInfo.compressed)
3781*8975f5c5SAndroid Build Coastguard Worker     {
3782*8975f5c5SAndroid Build Coastguard Worker         GLenum uncompressedFormat = (!srcFormatInfo.compressed) ? srcFormatInfo.internalFormat
3783*8975f5c5SAndroid Build Coastguard Worker                                                                 : dstFormatInfo.internalFormat;
3784*8975f5c5SAndroid Build Coastguard Worker         GLenum compressedFormat   = (srcFormatInfo.compressed) ? srcFormatInfo.internalFormat
3785*8975f5c5SAndroid Build Coastguard Worker                                                                : dstFormatInfo.internalFormat;
3786*8975f5c5SAndroid Build Coastguard Worker 
3787*8975f5c5SAndroid Build Coastguard Worker         return ValidateCopyMixedFormatCompatible(uncompressedFormat, compressedFormat);
3788*8975f5c5SAndroid Build Coastguard Worker     }
3789*8975f5c5SAndroid Build Coastguard Worker 
3790*8975f5c5SAndroid Build Coastguard Worker     if (!srcFormatInfo.compressed)
3791*8975f5c5SAndroid Build Coastguard Worker     {
3792*8975f5c5SAndroid Build Coastguard Worker         // Source and destination are uncompressed formats.
3793*8975f5c5SAndroid Build Coastguard Worker         return (srcFormatInfo.pixelBytes == dstFormatInfo.pixelBytes);
3794*8975f5c5SAndroid Build Coastguard Worker     }
3795*8975f5c5SAndroid Build Coastguard Worker 
3796*8975f5c5SAndroid Build Coastguard Worker     return ValidateCopyCompressedFormatCompatible(srcFormatInfo, dstFormatInfo);
3797*8975f5c5SAndroid Build Coastguard Worker }
3798*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyImageSubDataBase(const Context * context,angle::EntryPoint entryPoint,GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)3799*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyImageSubDataBase(const Context *context,
3800*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
3801*8975f5c5SAndroid Build Coastguard Worker                                   GLuint srcName,
3802*8975f5c5SAndroid Build Coastguard Worker                                   GLenum srcTarget,
3803*8975f5c5SAndroid Build Coastguard Worker                                   GLint srcLevel,
3804*8975f5c5SAndroid Build Coastguard Worker                                   GLint srcX,
3805*8975f5c5SAndroid Build Coastguard Worker                                   GLint srcY,
3806*8975f5c5SAndroid Build Coastguard Worker                                   GLint srcZ,
3807*8975f5c5SAndroid Build Coastguard Worker                                   GLuint dstName,
3808*8975f5c5SAndroid Build Coastguard Worker                                   GLenum dstTarget,
3809*8975f5c5SAndroid Build Coastguard Worker                                   GLint dstLevel,
3810*8975f5c5SAndroid Build Coastguard Worker                                   GLint dstX,
3811*8975f5c5SAndroid Build Coastguard Worker                                   GLint dstY,
3812*8975f5c5SAndroid Build Coastguard Worker                                   GLint dstZ,
3813*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei srcWidth,
3814*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei srcHeight,
3815*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei srcDepth)
3816*8975f5c5SAndroid Build Coastguard Worker {
3817*8975f5c5SAndroid Build Coastguard Worker     // INVALID_VALUE is generated if the dimensions of the either subregion exceeds the boundaries
3818*8975f5c5SAndroid Build Coastguard Worker     // of the corresponding image object
3819*8975f5c5SAndroid Build Coastguard Worker     if ((srcWidth < 0) || (srcHeight < 0) || (srcDepth < 0))
3820*8975f5c5SAndroid Build Coastguard Worker     {
3821*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3822*8975f5c5SAndroid Build Coastguard Worker         return false;
3823*8975f5c5SAndroid Build Coastguard Worker     }
3824*8975f5c5SAndroid Build Coastguard Worker 
3825*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyImageSubDataTarget(context, entryPoint, srcName, srcTarget))
3826*8975f5c5SAndroid Build Coastguard Worker     {
3827*8975f5c5SAndroid Build Coastguard Worker         return false;
3828*8975f5c5SAndroid Build Coastguard Worker     }
3829*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyImageSubDataTarget(context, entryPoint, dstName, dstTarget))
3830*8975f5c5SAndroid Build Coastguard Worker     {
3831*8975f5c5SAndroid Build Coastguard Worker         return false;
3832*8975f5c5SAndroid Build Coastguard Worker     }
3833*8975f5c5SAndroid Build Coastguard Worker 
3834*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyImageSubDataLevel(context, entryPoint, srcTarget, srcLevel))
3835*8975f5c5SAndroid Build Coastguard Worker     {
3836*8975f5c5SAndroid Build Coastguard Worker         return false;
3837*8975f5c5SAndroid Build Coastguard Worker     }
3838*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyImageSubDataLevel(context, entryPoint, dstTarget, dstLevel))
3839*8975f5c5SAndroid Build Coastguard Worker     {
3840*8975f5c5SAndroid Build Coastguard Worker         return false;
3841*8975f5c5SAndroid Build Coastguard Worker     }
3842*8975f5c5SAndroid Build Coastguard Worker 
3843*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &srcFormatInfo =
3844*8975f5c5SAndroid Build Coastguard Worker         GetTargetFormatInfo(context, entryPoint, srcName, srcTarget, srcLevel);
3845*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &dstFormatInfo =
3846*8975f5c5SAndroid Build Coastguard Worker         GetTargetFormatInfo(context, entryPoint, dstName, dstTarget, dstLevel);
3847*8975f5c5SAndroid Build Coastguard Worker     GLsizei dstWidth   = srcWidth;
3848*8975f5c5SAndroid Build Coastguard Worker     GLsizei dstHeight  = srcHeight;
3849*8975f5c5SAndroid Build Coastguard Worker     GLsizei srcSamples = 1;
3850*8975f5c5SAndroid Build Coastguard Worker     GLsizei dstSamples = 1;
3851*8975f5c5SAndroid Build Coastguard Worker 
3852*8975f5c5SAndroid Build Coastguard Worker     if (srcFormatInfo.internalFormat == GL_NONE || dstFormatInfo.internalFormat == GL_NONE)
3853*8975f5c5SAndroid Build Coastguard Worker     {
3854*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureLevel);
3855*8975f5c5SAndroid Build Coastguard Worker         return false;
3856*8975f5c5SAndroid Build Coastguard Worker     }
3857*8975f5c5SAndroid Build Coastguard Worker 
3858*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, srcName, srcTarget, srcLevel,
3859*8975f5c5SAndroid Build Coastguard Worker                                               srcX, srcY, srcZ, srcWidth, srcHeight, &srcSamples))
3860*8975f5c5SAndroid Build Coastguard Worker     {
3861*8975f5c5SAndroid Build Coastguard Worker         return false;
3862*8975f5c5SAndroid Build Coastguard Worker     }
3863*8975f5c5SAndroid Build Coastguard Worker 
3864*8975f5c5SAndroid Build Coastguard Worker     // When copying from a compressed image to an uncompressed image the image texel dimensions
3865*8975f5c5SAndroid Build Coastguard Worker     // written to the uncompressed image will be source extent divided by the compressed texel block
3866*8975f5c5SAndroid Build Coastguard Worker     // dimensions.
3867*8975f5c5SAndroid Build Coastguard Worker     if ((srcFormatInfo.compressed) && (!dstFormatInfo.compressed))
3868*8975f5c5SAndroid Build Coastguard Worker     {
3869*8975f5c5SAndroid Build Coastguard Worker         ASSERT(srcFormatInfo.compressedBlockWidth != 0);
3870*8975f5c5SAndroid Build Coastguard Worker         ASSERT(srcFormatInfo.compressedBlockHeight != 0);
3871*8975f5c5SAndroid Build Coastguard Worker 
3872*8975f5c5SAndroid Build Coastguard Worker         dstWidth /= srcFormatInfo.compressedBlockWidth;
3873*8975f5c5SAndroid Build Coastguard Worker         dstHeight /= srcFormatInfo.compressedBlockHeight;
3874*8975f5c5SAndroid Build Coastguard Worker     }
3875*8975f5c5SAndroid Build Coastguard Worker     // When copying from an uncompressed image to a compressed image the image texel dimensions
3876*8975f5c5SAndroid Build Coastguard Worker     // written to the compressed image will be the source extent multiplied by the compressed texel
3877*8975f5c5SAndroid Build Coastguard Worker     // block dimensions.
3878*8975f5c5SAndroid Build Coastguard Worker     else if ((!srcFormatInfo.compressed) && (dstFormatInfo.compressed))
3879*8975f5c5SAndroid Build Coastguard Worker     {
3880*8975f5c5SAndroid Build Coastguard Worker         dstWidth *= dstFormatInfo.compressedBlockWidth;
3881*8975f5c5SAndroid Build Coastguard Worker         dstHeight *= dstFormatInfo.compressedBlockHeight;
3882*8975f5c5SAndroid Build Coastguard Worker     }
3883*8975f5c5SAndroid Build Coastguard Worker 
3884*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyImageSubDataTargetRegion(context, entryPoint, dstName, dstTarget, dstLevel,
3885*8975f5c5SAndroid Build Coastguard Worker                                               dstX, dstY, dstZ, dstWidth, dstHeight, &dstSamples))
3886*8975f5c5SAndroid Build Coastguard Worker     {
3887*8975f5c5SAndroid Build Coastguard Worker         return false;
3888*8975f5c5SAndroid Build Coastguard Worker     }
3889*8975f5c5SAndroid Build Coastguard Worker 
3890*8975f5c5SAndroid Build Coastguard Worker     bool fillsEntireMip               = false;
3891*8975f5c5SAndroid Build Coastguard Worker     gl::Texture *dstTexture           = context->getTexture({dstName});
3892*8975f5c5SAndroid Build Coastguard Worker     gl::TextureTarget dstTargetPacked = gl::PackParam<gl::TextureTarget>(dstTarget);
3893*8975f5c5SAndroid Build Coastguard Worker     // TODO(http://anglebug.com/42264179): Some targets (e.g., GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER)
3894*8975f5c5SAndroid Build Coastguard Worker     // are unsupported when used with compressed formats due to gl::PackParam() returning
3895*8975f5c5SAndroid Build Coastguard Worker     // TextureTarget::InvalidEnum.
3896*8975f5c5SAndroid Build Coastguard Worker     if (dstTargetPacked != gl::TextureTarget::InvalidEnum)
3897*8975f5c5SAndroid Build Coastguard Worker     {
3898*8975f5c5SAndroid Build Coastguard Worker         const gl::Extents &dstExtents = dstTexture->getExtents(dstTargetPacked, dstLevel);
3899*8975f5c5SAndroid Build Coastguard Worker         fillsEntireMip = dstX == 0 && dstY == 0 && dstZ == 0 && srcWidth == dstExtents.width &&
3900*8975f5c5SAndroid Build Coastguard Worker                          srcHeight == dstExtents.height && srcDepth == dstExtents.depth;
3901*8975f5c5SAndroid Build Coastguard Worker     }
3902*8975f5c5SAndroid Build Coastguard Worker 
3903*8975f5c5SAndroid Build Coastguard Worker     if (srcFormatInfo.compressed && !fillsEntireMip &&
3904*8975f5c5SAndroid Build Coastguard Worker         !ValidateCompressedRegion(context, entryPoint, srcFormatInfo, srcWidth, srcHeight))
3905*8975f5c5SAndroid Build Coastguard Worker     {
3906*8975f5c5SAndroid Build Coastguard Worker         return false;
3907*8975f5c5SAndroid Build Coastguard Worker     }
3908*8975f5c5SAndroid Build Coastguard Worker 
3909*8975f5c5SAndroid Build Coastguard Worker     if (dstFormatInfo.compressed && !fillsEntireMip &&
3910*8975f5c5SAndroid Build Coastguard Worker         !ValidateCompressedRegion(context, entryPoint, dstFormatInfo, dstWidth, dstHeight))
3911*8975f5c5SAndroid Build Coastguard Worker     {
3912*8975f5c5SAndroid Build Coastguard Worker         return false;
3913*8975f5c5SAndroid Build Coastguard Worker     }
3914*8975f5c5SAndroid Build Coastguard Worker 
3915*8975f5c5SAndroid Build Coastguard Worker     // From EXT_copy_image: INVALID_OPERATION is generated if the source and destination formats
3916*8975f5c5SAndroid Build Coastguard Worker     // are not compatible, if one image is compressed and the other is uncompressed and the block
3917*8975f5c5SAndroid Build Coastguard Worker     // size of compressed image is not equal to the texel size of the compressed image.
3918*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateCopyFormatCompatible(srcFormatInfo, dstFormatInfo))
3919*8975f5c5SAndroid Build Coastguard Worker     {
3920*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIncompatibleTextures);
3921*8975f5c5SAndroid Build Coastguard Worker         return false;
3922*8975f5c5SAndroid Build Coastguard Worker     }
3923*8975f5c5SAndroid Build Coastguard Worker 
3924*8975f5c5SAndroid Build Coastguard Worker     // INVALID_OPERATION is generated if the source and destination number of samples do not match
3925*8975f5c5SAndroid Build Coastguard Worker     if (srcSamples != dstSamples)
3926*8975f5c5SAndroid Build Coastguard Worker     {
3927*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
3928*8975f5c5SAndroid Build Coastguard Worker         return false;
3929*8975f5c5SAndroid Build Coastguard Worker     }
3930*8975f5c5SAndroid Build Coastguard Worker 
3931*8975f5c5SAndroid Build Coastguard Worker     return true;
3932*8975f5c5SAndroid Build Coastguard Worker }
3933*8975f5c5SAndroid Build Coastguard Worker 
ValidateCopyTexImageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border,Format * textureFormatOut)3934*8975f5c5SAndroid Build Coastguard Worker bool ValidateCopyTexImageParametersBase(const Context *context,
3935*8975f5c5SAndroid Build Coastguard Worker                                         angle::EntryPoint entryPoint,
3936*8975f5c5SAndroid Build Coastguard Worker                                         TextureTarget target,
3937*8975f5c5SAndroid Build Coastguard Worker                                         GLint level,
3938*8975f5c5SAndroid Build Coastguard Worker                                         GLenum internalformat,
3939*8975f5c5SAndroid Build Coastguard Worker                                         bool isSubImage,
3940*8975f5c5SAndroid Build Coastguard Worker                                         GLint xoffset,
3941*8975f5c5SAndroid Build Coastguard Worker                                         GLint yoffset,
3942*8975f5c5SAndroid Build Coastguard Worker                                         GLint zoffset,
3943*8975f5c5SAndroid Build Coastguard Worker                                         GLint x,
3944*8975f5c5SAndroid Build Coastguard Worker                                         GLint y,
3945*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei width,
3946*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei height,
3947*8975f5c5SAndroid Build Coastguard Worker                                         GLint border,
3948*8975f5c5SAndroid Build Coastguard Worker                                         Format *textureFormatOut)
3949*8975f5c5SAndroid Build Coastguard Worker {
3950*8975f5c5SAndroid Build Coastguard Worker     TextureType texType = TextureTargetToType(target);
3951*8975f5c5SAndroid Build Coastguard Worker 
3952*8975f5c5SAndroid Build Coastguard Worker     if (xoffset < 0 || yoffset < 0 || zoffset < 0)
3953*8975f5c5SAndroid Build Coastguard Worker     {
3954*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3955*8975f5c5SAndroid Build Coastguard Worker         return false;
3956*8975f5c5SAndroid Build Coastguard Worker     }
3957*8975f5c5SAndroid Build Coastguard Worker 
3958*8975f5c5SAndroid Build Coastguard Worker     if (width < 0 || height < 0)
3959*8975f5c5SAndroid Build Coastguard Worker     {
3960*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3961*8975f5c5SAndroid Build Coastguard Worker         return false;
3962*8975f5c5SAndroid Build Coastguard Worker     }
3963*8975f5c5SAndroid Build Coastguard Worker 
3964*8975f5c5SAndroid Build Coastguard Worker     if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
3965*8975f5c5SAndroid Build Coastguard Worker         std::numeric_limits<GLsizei>::max() - yoffset < height)
3966*8975f5c5SAndroid Build Coastguard Worker     {
3967*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
3968*8975f5c5SAndroid Build Coastguard Worker         return false;
3969*8975f5c5SAndroid Build Coastguard Worker     }
3970*8975f5c5SAndroid Build Coastguard Worker 
3971*8975f5c5SAndroid Build Coastguard Worker     if (std::numeric_limits<GLint>::max() - width < x ||
3972*8975f5c5SAndroid Build Coastguard Worker         std::numeric_limits<GLint>::max() - height < y)
3973*8975f5c5SAndroid Build Coastguard Worker     {
3974*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIntegerOverflow);
3975*8975f5c5SAndroid Build Coastguard Worker         return false;
3976*8975f5c5SAndroid Build Coastguard Worker     }
3977*8975f5c5SAndroid Build Coastguard Worker 
3978*8975f5c5SAndroid Build Coastguard Worker     if (border != 0)
3979*8975f5c5SAndroid Build Coastguard Worker     {
3980*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBorder);
3981*8975f5c5SAndroid Build Coastguard Worker         return false;
3982*8975f5c5SAndroid Build Coastguard Worker     }
3983*8975f5c5SAndroid Build Coastguard Worker 
3984*8975f5c5SAndroid Build Coastguard Worker     if (!ValidMipLevel(context, texType, level))
3985*8975f5c5SAndroid Build Coastguard Worker     {
3986*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3987*8975f5c5SAndroid Build Coastguard Worker         return false;
3988*8975f5c5SAndroid Build Coastguard Worker     }
3989*8975f5c5SAndroid Build Coastguard Worker 
3990*8975f5c5SAndroid Build Coastguard Worker     const State &state           = context->getState();
3991*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *readFramebuffer = state.getReadFramebuffer();
3992*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
3993*8975f5c5SAndroid Build Coastguard Worker     {
3994*8975f5c5SAndroid Build Coastguard Worker         return false;
3995*8975f5c5SAndroid Build Coastguard Worker     }
3996*8975f5c5SAndroid Build Coastguard Worker 
3997*8975f5c5SAndroid Build Coastguard Worker     // checkReadBufferResourceSamples = true. Treat renderToTexture textures as single sample since
3998*8975f5c5SAndroid Build Coastguard Worker     // they will be resolved before copying.
3999*8975f5c5SAndroid Build Coastguard Worker     if (!readFramebuffer->isDefault() &&
4000*8975f5c5SAndroid Build Coastguard Worker         !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true))
4001*8975f5c5SAndroid Build Coastguard Worker     {
4002*8975f5c5SAndroid Build Coastguard Worker         return false;
4003*8975f5c5SAndroid Build Coastguard Worker     }
4004*8975f5c5SAndroid Build Coastguard Worker 
4005*8975f5c5SAndroid Build Coastguard Worker     if (readFramebuffer->getReadBufferState() == GL_NONE)
4006*8975f5c5SAndroid Build Coastguard Worker     {
4007*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNone);
4008*8975f5c5SAndroid Build Coastguard Worker         return false;
4009*8975f5c5SAndroid Build Coastguard Worker     }
4010*8975f5c5SAndroid Build Coastguard Worker 
4011*8975f5c5SAndroid Build Coastguard Worker     // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
4012*8975f5c5SAndroid Build Coastguard Worker     // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
4013*8975f5c5SAndroid Build Coastguard Worker     // attachment and WebGL defines it to be an error. We do the check unconditionally as the
4014*8975f5c5SAndroid Build Coastguard Worker     // situation is an application error that would lead to a crash in ANGLE.
4015*8975f5c5SAndroid Build Coastguard Worker     const FramebufferAttachment *source = readFramebuffer->getReadColorAttachment();
4016*8975f5c5SAndroid Build Coastguard Worker     if (source == nullptr)
4017*8975f5c5SAndroid Build Coastguard Worker     {
4018*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingReadAttachment);
4019*8975f5c5SAndroid Build Coastguard Worker         return false;
4020*8975f5c5SAndroid Build Coastguard Worker     }
4021*8975f5c5SAndroid Build Coastguard Worker 
4022*8975f5c5SAndroid Build Coastguard Worker     if (source->isYUV())
4023*8975f5c5SAndroid Build Coastguard Worker     {
4024*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCopyFromYUVFramebuffer);
4025*8975f5c5SAndroid Build Coastguard Worker         return false;
4026*8975f5c5SAndroid Build Coastguard Worker     }
4027*8975f5c5SAndroid Build Coastguard Worker 
4028*8975f5c5SAndroid Build Coastguard Worker     // OVR_multiview spec:
4029*8975f5c5SAndroid Build Coastguard Worker     // INVALID_FRAMEBUFFER_OPERATION is generated by commands that read from the
4030*8975f5c5SAndroid Build Coastguard Worker     // framebuffer such as BlitFramebuffer, ReadPixels, CopyTexImage*, and
4031*8975f5c5SAndroid Build Coastguard Worker     // CopyTexSubImage*, if the number of views in the current read framebuffer
4032*8975f5c5SAndroid Build Coastguard Worker     // is greater than 1.
4033*8975f5c5SAndroid Build Coastguard Worker     if (readFramebuffer->readDisallowedByMultiview())
4034*8975f5c5SAndroid Build Coastguard Worker     {
4035*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
4036*8975f5c5SAndroid Build Coastguard Worker         return false;
4037*8975f5c5SAndroid Build Coastguard Worker     }
4038*8975f5c5SAndroid Build Coastguard Worker 
4039*8975f5c5SAndroid Build Coastguard Worker     const Caps &caps = context->getCaps();
4040*8975f5c5SAndroid Build Coastguard Worker 
4041*8975f5c5SAndroid Build Coastguard Worker     GLint maxDimension = 0;
4042*8975f5c5SAndroid Build Coastguard Worker     switch (texType)
4043*8975f5c5SAndroid Build Coastguard Worker     {
4044*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2D:
4045*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max2DTextureSize;
4046*8975f5c5SAndroid Build Coastguard Worker             break;
4047*8975f5c5SAndroid Build Coastguard Worker 
4048*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMap:
4049*8975f5c5SAndroid Build Coastguard Worker         case TextureType::CubeMapArray:
4050*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.maxCubeMapTextureSize;
4051*8975f5c5SAndroid Build Coastguard Worker             break;
4052*8975f5c5SAndroid Build Coastguard Worker 
4053*8975f5c5SAndroid Build Coastguard Worker         case TextureType::Rectangle:
4054*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.maxRectangleTextureSize;
4055*8975f5c5SAndroid Build Coastguard Worker             break;
4056*8975f5c5SAndroid Build Coastguard Worker 
4057*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DArray:
4058*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max2DTextureSize;
4059*8975f5c5SAndroid Build Coastguard Worker             break;
4060*8975f5c5SAndroid Build Coastguard Worker 
4061*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_3D:
4062*8975f5c5SAndroid Build Coastguard Worker             maxDimension = caps.max3DTextureSize;
4063*8975f5c5SAndroid Build Coastguard Worker             break;
4064*8975f5c5SAndroid Build Coastguard Worker 
4065*8975f5c5SAndroid Build Coastguard Worker         default:
4066*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
4067*8975f5c5SAndroid Build Coastguard Worker             return false;
4068*8975f5c5SAndroid Build Coastguard Worker     }
4069*8975f5c5SAndroid Build Coastguard Worker 
4070*8975f5c5SAndroid Build Coastguard Worker     Texture *texture = state.getTargetTexture(texType);
4071*8975f5c5SAndroid Build Coastguard Worker     if (!texture)
4072*8975f5c5SAndroid Build Coastguard Worker     {
4073*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureNotBound);
4074*8975f5c5SAndroid Build Coastguard Worker         return false;
4075*8975f5c5SAndroid Build Coastguard Worker     }
4076*8975f5c5SAndroid Build Coastguard Worker 
4077*8975f5c5SAndroid Build Coastguard Worker     if (texture->getImmutableFormat() && !isSubImage)
4078*8975f5c5SAndroid Build Coastguard Worker     {
4079*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsImmutable);
4080*8975f5c5SAndroid Build Coastguard Worker         return false;
4081*8975f5c5SAndroid Build Coastguard Worker     }
4082*8975f5c5SAndroid Build Coastguard Worker 
4083*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo =
4084*8975f5c5SAndroid Build Coastguard Worker         isSubImage ? *texture->getFormat(target, level).info
4085*8975f5c5SAndroid Build Coastguard Worker                    : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
4086*8975f5c5SAndroid Build Coastguard Worker 
4087*8975f5c5SAndroid Build Coastguard Worker     if (formatInfo.depthBits > 0 || formatInfo.compressed)
4088*8975f5c5SAndroid Build Coastguard Worker     {
4089*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
4090*8975f5c5SAndroid Build Coastguard Worker         return false;
4091*8975f5c5SAndroid Build Coastguard Worker     }
4092*8975f5c5SAndroid Build Coastguard Worker 
4093*8975f5c5SAndroid Build Coastguard Worker     if (isSubImage)
4094*8975f5c5SAndroid Build Coastguard Worker     {
4095*8975f5c5SAndroid Build Coastguard Worker         if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
4096*8975f5c5SAndroid Build Coastguard Worker             static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
4097*8975f5c5SAndroid Build Coastguard Worker             static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
4098*8975f5c5SAndroid Build Coastguard Worker         {
4099*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
4100*8975f5c5SAndroid Build Coastguard Worker             return false;
4101*8975f5c5SAndroid Build Coastguard Worker         }
4102*8975f5c5SAndroid Build Coastguard Worker     }
4103*8975f5c5SAndroid Build Coastguard Worker     else
4104*8975f5c5SAndroid Build Coastguard Worker     {
4105*8975f5c5SAndroid Build Coastguard Worker         if ((texType == TextureType::CubeMap || texType == TextureType::CubeMapArray) &&
4106*8975f5c5SAndroid Build Coastguard Worker             width != height)
4107*8975f5c5SAndroid Build Coastguard Worker         {
4108*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapIncomplete);
4109*8975f5c5SAndroid Build Coastguard Worker             return false;
4110*8975f5c5SAndroid Build Coastguard Worker         }
4111*8975f5c5SAndroid Build Coastguard Worker 
4112*8975f5c5SAndroid Build Coastguard Worker         if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
4113*8975f5c5SAndroid Build Coastguard Worker         {
4114*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, internalformat);
4115*8975f5c5SAndroid Build Coastguard Worker             return false;
4116*8975f5c5SAndroid Build Coastguard Worker         }
4117*8975f5c5SAndroid Build Coastguard Worker 
4118*8975f5c5SAndroid Build Coastguard Worker         int maxLevelDimension = (maxDimension >> level);
4119*8975f5c5SAndroid Build Coastguard Worker         if (static_cast<int>(width) > maxLevelDimension ||
4120*8975f5c5SAndroid Build Coastguard Worker             static_cast<int>(height) > maxLevelDimension)
4121*8975f5c5SAndroid Build Coastguard Worker         {
4122*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
4123*8975f5c5SAndroid Build Coastguard Worker             return false;
4124*8975f5c5SAndroid Build Coastguard Worker         }
4125*8975f5c5SAndroid Build Coastguard Worker     }
4126*8975f5c5SAndroid Build Coastguard Worker 
4127*8975f5c5SAndroid Build Coastguard Worker     // Do not leak the previous texture format for non-subImage case.
4128*8975f5c5SAndroid Build Coastguard Worker     if (textureFormatOut && isSubImage)
4129*8975f5c5SAndroid Build Coastguard Worker     {
4130*8975f5c5SAndroid Build Coastguard Worker         *textureFormatOut = texture->getFormat(target, level);
4131*8975f5c5SAndroid Build Coastguard Worker     }
4132*8975f5c5SAndroid Build Coastguard Worker 
4133*8975f5c5SAndroid Build Coastguard Worker     // Detect texture copying feedback loops for WebGL.
4134*8975f5c5SAndroid Build Coastguard Worker     if (context->isWebGL())
4135*8975f5c5SAndroid Build Coastguard Worker     {
4136*8975f5c5SAndroid Build Coastguard Worker         if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
4137*8975f5c5SAndroid Build Coastguard Worker         {
4138*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFeedbackLoop);
4139*8975f5c5SAndroid Build Coastguard Worker             return false;
4140*8975f5c5SAndroid Build Coastguard Worker         }
4141*8975f5c5SAndroid Build Coastguard Worker     }
4142*8975f5c5SAndroid Build Coastguard Worker 
4143*8975f5c5SAndroid Build Coastguard Worker     return true;
4144*8975f5c5SAndroid Build Coastguard Worker }
4145*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramPipelineDrawStates(const Context * context,const Extensions & extensions,ProgramPipeline * programPipeline)4146*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramPipelineDrawStates(const Context *context,
4147*8975f5c5SAndroid Build Coastguard Worker                                               const Extensions &extensions,
4148*8975f5c5SAndroid Build Coastguard Worker                                               ProgramPipeline *programPipeline)
4149*8975f5c5SAndroid Build Coastguard Worker {
4150*8975f5c5SAndroid Build Coastguard Worker     for (const ShaderType shaderType : gl::AllShaderTypes())
4151*8975f5c5SAndroid Build Coastguard Worker     {
4152*8975f5c5SAndroid Build Coastguard Worker         const SharedProgramExecutable &executable =
4153*8975f5c5SAndroid Build Coastguard Worker             programPipeline->getShaderProgramExecutable(shaderType);
4154*8975f5c5SAndroid Build Coastguard Worker         if (executable)
4155*8975f5c5SAndroid Build Coastguard Worker         {
4156*8975f5c5SAndroid Build Coastguard Worker             const char *errorMsg = ValidateProgramDrawStates(context, extensions, *executable);
4157*8975f5c5SAndroid Build Coastguard Worker             if (errorMsg)
4158*8975f5c5SAndroid Build Coastguard Worker             {
4159*8975f5c5SAndroid Build Coastguard Worker                 return errorMsg;
4160*8975f5c5SAndroid Build Coastguard Worker             }
4161*8975f5c5SAndroid Build Coastguard Worker         }
4162*8975f5c5SAndroid Build Coastguard Worker     }
4163*8975f5c5SAndroid Build Coastguard Worker 
4164*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
4165*8975f5c5SAndroid Build Coastguard Worker }
4166*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramPipelineAttachedPrograms(ProgramPipeline * programPipeline)4167*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline)
4168*8975f5c5SAndroid Build Coastguard Worker {
4169*8975f5c5SAndroid Build Coastguard Worker     // An INVALID_OPERATION error is generated by any command that transfers vertices to the
4170*8975f5c5SAndroid Build Coastguard Worker     // GL or launches compute work if the current set of active
4171*8975f5c5SAndroid Build Coastguard Worker     // program objects cannot be executed, for reasons including:
4172*8975f5c5SAndroid Build Coastguard Worker     // - There is no current program object specified by UseProgram, there is a current program
4173*8975f5c5SAndroid Build Coastguard Worker     //    pipeline object, and that object is empty (no executable code is installed for any stage).
4174*8975f5c5SAndroid Build Coastguard Worker     // - A program object is active for at least one, but not all of the shader
4175*8975f5c5SAndroid Build Coastguard Worker     // stages that were present when the program was linked.
4176*8975f5c5SAndroid Build Coastguard Worker     if (!programPipeline->getExecutable().getLinkedShaderStages().any())
4177*8975f5c5SAndroid Build Coastguard Worker     {
4178*8975f5c5SAndroid Build Coastguard Worker         return gl::err::kNoExecutableCodeInstalled;
4179*8975f5c5SAndroid Build Coastguard Worker     }
4180*8975f5c5SAndroid Build Coastguard Worker     for (const ShaderType shaderType : gl::AllShaderTypes())
4181*8975f5c5SAndroid Build Coastguard Worker     {
4182*8975f5c5SAndroid Build Coastguard Worker         const Program *shaderProgram = programPipeline->getShaderProgram(shaderType);
4183*8975f5c5SAndroid Build Coastguard Worker         if (shaderProgram)
4184*8975f5c5SAndroid Build Coastguard Worker         {
4185*8975f5c5SAndroid Build Coastguard Worker             const ProgramExecutable &executable = shaderProgram->getExecutable();
4186*8975f5c5SAndroid Build Coastguard Worker             for (const ShaderType programShaderType : executable.getLinkedShaderStages())
4187*8975f5c5SAndroid Build Coastguard Worker             {
4188*8975f5c5SAndroid Build Coastguard Worker                 if (shaderProgram != programPipeline->getShaderProgram(programShaderType))
4189*8975f5c5SAndroid Build Coastguard Worker                 {
4190*8975f5c5SAndroid Build Coastguard Worker                     return gl::err::kNotAllStagesOfSeparableProgramUsed;
4191*8975f5c5SAndroid Build Coastguard Worker                 }
4192*8975f5c5SAndroid Build Coastguard Worker             }
4193*8975f5c5SAndroid Build Coastguard Worker         }
4194*8975f5c5SAndroid Build Coastguard Worker     }
4195*8975f5c5SAndroid Build Coastguard Worker 
4196*8975f5c5SAndroid Build Coastguard Worker     // [EXT_geometry_shader] Section 11.1.gs Geometry Shaders
4197*8975f5c5SAndroid Build Coastguard Worker     // A non-separable program object or program pipeline object that includes
4198*8975f5c5SAndroid Build Coastguard Worker     // a geometry shader must also include a vertex shader.
4199*8975f5c5SAndroid Build Coastguard Worker     // An INVALID_OPERATION error is generated by any command that transfers
4200*8975f5c5SAndroid Build Coastguard Worker     // vertices to the GL if the current program state has a geometry shader
4201*8975f5c5SAndroid Build Coastguard Worker     // but no vertex shader.
4202*8975f5c5SAndroid Build Coastguard Worker     if (!programPipeline->getShaderProgram(ShaderType::Vertex) &&
4203*8975f5c5SAndroid Build Coastguard Worker         programPipeline->getShaderProgram(ShaderType::Geometry))
4204*8975f5c5SAndroid Build Coastguard Worker     {
4205*8975f5c5SAndroid Build Coastguard Worker         return gl::err::kNoActiveGraphicsShaderStage;
4206*8975f5c5SAndroid Build Coastguard Worker     }
4207*8975f5c5SAndroid Build Coastguard Worker 
4208*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
4209*8975f5c5SAndroid Build Coastguard Worker }
4210*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawStates(const Context * context,GLenum * outErrorCode)4211*8975f5c5SAndroid Build Coastguard Worker const char *ValidateDrawStates(const Context *context, GLenum *outErrorCode)
4212*8975f5c5SAndroid Build Coastguard Worker {
4213*8975f5c5SAndroid Build Coastguard Worker     // Note all errors returned from this function are INVALID_OPERATION except for the draw
4214*8975f5c5SAndroid Build Coastguard Worker     // framebuffer completeness check.
4215*8975f5c5SAndroid Build Coastguard Worker     *outErrorCode = GL_INVALID_OPERATION;
4216*8975f5c5SAndroid Build Coastguard Worker 
4217*8975f5c5SAndroid Build Coastguard Worker     const Extensions &extensions = context->getExtensions();
4218*8975f5c5SAndroid Build Coastguard Worker     const State &state           = context->getState();
4219*8975f5c5SAndroid Build Coastguard Worker 
4220*8975f5c5SAndroid Build Coastguard Worker     // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
4221*8975f5c5SAndroid Build Coastguard Worker     // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
4222*8975f5c5SAndroid Build Coastguard Worker     // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
4223*8975f5c5SAndroid Build Coastguard Worker     VertexArray *vertexArray = state.getVertexArray();
4224*8975f5c5SAndroid Build Coastguard Worker     ASSERT(vertexArray);
4225*8975f5c5SAndroid Build Coastguard Worker 
4226*8975f5c5SAndroid Build Coastguard Worker     if (!extensions.webglCompatibilityANGLE && vertexArray->hasInvalidMappedArrayBuffer())
4227*8975f5c5SAndroid Build Coastguard Worker     {
4228*8975f5c5SAndroid Build Coastguard Worker         return kBufferMapped;
4229*8975f5c5SAndroid Build Coastguard Worker     }
4230*8975f5c5SAndroid Build Coastguard Worker 
4231*8975f5c5SAndroid Build Coastguard Worker     // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
4232*8975f5c5SAndroid Build Coastguard Worker     // Section 6.10 of the WebGL 1.0 spec.
4233*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *framebuffer = state.getDrawFramebuffer();
4234*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebuffer);
4235*8975f5c5SAndroid Build Coastguard Worker 
4236*8975f5c5SAndroid Build Coastguard Worker     if (context->getLimitations().noSeparateStencilRefsAndMasks ||
4237*8975f5c5SAndroid Build Coastguard Worker         extensions.webglCompatibilityANGLE)
4238*8975f5c5SAndroid Build Coastguard Worker     {
4239*8975f5c5SAndroid Build Coastguard Worker         ASSERT(framebuffer);
4240*8975f5c5SAndroid Build Coastguard Worker         const FramebufferAttachment *dsAttachment =
4241*8975f5c5SAndroid Build Coastguard Worker             framebuffer->getStencilOrDepthStencilAttachment();
4242*8975f5c5SAndroid Build Coastguard Worker         const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
4243*8975f5c5SAndroid Build Coastguard Worker         ASSERT(stencilBits <= 8);
4244*8975f5c5SAndroid Build Coastguard Worker 
4245*8975f5c5SAndroid Build Coastguard Worker         const DepthStencilState &depthStencilState = state.getDepthStencilState();
4246*8975f5c5SAndroid Build Coastguard Worker         if (depthStencilState.stencilTest && stencilBits > 0)
4247*8975f5c5SAndroid Build Coastguard Worker         {
4248*8975f5c5SAndroid Build Coastguard Worker             auto maxStencilValue = angle::BitMask<GLuint>(stencilBits);
4249*8975f5c5SAndroid Build Coastguard Worker 
4250*8975f5c5SAndroid Build Coastguard Worker             bool differentRefs =
4251*8975f5c5SAndroid Build Coastguard Worker                 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
4252*8975f5c5SAndroid Build Coastguard Worker                 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
4253*8975f5c5SAndroid Build Coastguard Worker             bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
4254*8975f5c5SAndroid Build Coastguard Worker                                        (depthStencilState.stencilBackWritemask & maxStencilValue);
4255*8975f5c5SAndroid Build Coastguard Worker             bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
4256*8975f5c5SAndroid Build Coastguard Worker                                   (depthStencilState.stencilBackMask & maxStencilValue);
4257*8975f5c5SAndroid Build Coastguard Worker 
4258*8975f5c5SAndroid Build Coastguard Worker             if (differentRefs || differentWritemasks || differentMasks)
4259*8975f5c5SAndroid Build Coastguard Worker             {
4260*8975f5c5SAndroid Build Coastguard Worker                 if (!extensions.webglCompatibilityANGLE)
4261*8975f5c5SAndroid Build Coastguard Worker                 {
4262*8975f5c5SAndroid Build Coastguard Worker                     WARN() << "This ANGLE implementation does not support separate front/back "
4263*8975f5c5SAndroid Build Coastguard Worker                               "stencil writemasks, reference values, or stencil mask values.";
4264*8975f5c5SAndroid Build Coastguard Worker                 }
4265*8975f5c5SAndroid Build Coastguard Worker                 return kStencilReferenceMaskOrMismatch;
4266*8975f5c5SAndroid Build Coastguard Worker             }
4267*8975f5c5SAndroid Build Coastguard Worker         }
4268*8975f5c5SAndroid Build Coastguard Worker     }
4269*8975f5c5SAndroid Build Coastguard Worker 
4270*8975f5c5SAndroid Build Coastguard Worker     if (!extensions.floatBlendEXT)
4271*8975f5c5SAndroid Build Coastguard Worker     {
4272*8975f5c5SAndroid Build Coastguard Worker         const DrawBufferMask blendEnabledActiveFloat32ColorAttachmentDrawBufferMask =
4273*8975f5c5SAndroid Build Coastguard Worker             state.getBlendEnabledDrawBufferMask() &
4274*8975f5c5SAndroid Build Coastguard Worker             framebuffer->getActiveFloat32ColorAttachmentDrawBufferMask();
4275*8975f5c5SAndroid Build Coastguard Worker         if (blendEnabledActiveFloat32ColorAttachmentDrawBufferMask.any())
4276*8975f5c5SAndroid Build Coastguard Worker         {
4277*8975f5c5SAndroid Build Coastguard Worker             return kUnsupportedFloatBlending;
4278*8975f5c5SAndroid Build Coastguard Worker         }
4279*8975f5c5SAndroid Build Coastguard Worker     }
4280*8975f5c5SAndroid Build Coastguard Worker 
4281*8975f5c5SAndroid Build Coastguard Worker     if (extensions.renderSharedExponentQCOM)
4282*8975f5c5SAndroid Build Coastguard Worker     {
4283*8975f5c5SAndroid Build Coastguard Worker         if (!ValidateColorMasksForSharedExponentColorBuffers(state.getBlendStateExt(), framebuffer))
4284*8975f5c5SAndroid Build Coastguard Worker         {
4285*8975f5c5SAndroid Build Coastguard Worker             return kUnsupportedColorMaskForSharedExponentColorBuffer;
4286*8975f5c5SAndroid Build Coastguard Worker         }
4287*8975f5c5SAndroid Build Coastguard Worker     }
4288*8975f5c5SAndroid Build Coastguard Worker 
4289*8975f5c5SAndroid Build Coastguard Worker     if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4290*8975f5c5SAndroid Build Coastguard Worker         extensions.webglCompatibilityANGLE)
4291*8975f5c5SAndroid Build Coastguard Worker     {
4292*8975f5c5SAndroid Build Coastguard Worker         if (state.hasSimultaneousConstantColorAndAlphaBlendFunc())
4293*8975f5c5SAndroid Build Coastguard Worker         {
4294*8975f5c5SAndroid Build Coastguard Worker             if (extensions.webglCompatibilityANGLE)
4295*8975f5c5SAndroid Build Coastguard Worker             {
4296*8975f5c5SAndroid Build Coastguard Worker                 return kInvalidConstantColor;
4297*8975f5c5SAndroid Build Coastguard Worker             }
4298*8975f5c5SAndroid Build Coastguard Worker 
4299*8975f5c5SAndroid Build Coastguard Worker             WARN() << kConstantColorAlphaLimitation;
4300*8975f5c5SAndroid Build Coastguard Worker             return kConstantColorAlphaLimitation;
4301*8975f5c5SAndroid Build Coastguard Worker         }
4302*8975f5c5SAndroid Build Coastguard Worker     }
4303*8975f5c5SAndroid Build Coastguard Worker 
4304*8975f5c5SAndroid Build Coastguard Worker     const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
4305*8975f5c5SAndroid Build Coastguard Worker     if (!framebufferStatus.isComplete())
4306*8975f5c5SAndroid Build Coastguard Worker     {
4307*8975f5c5SAndroid Build Coastguard Worker         *outErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION;
4308*8975f5c5SAndroid Build Coastguard Worker         ASSERT(framebufferStatus.reason);
4309*8975f5c5SAndroid Build Coastguard Worker         return framebufferStatus.reason;
4310*8975f5c5SAndroid Build Coastguard Worker     }
4311*8975f5c5SAndroid Build Coastguard Worker 
4312*8975f5c5SAndroid Build Coastguard Worker     bool framebufferIsYUV = framebuffer->hasYUVAttachment();
4313*8975f5c5SAndroid Build Coastguard Worker     if (framebufferIsYUV)
4314*8975f5c5SAndroid Build Coastguard Worker     {
4315*8975f5c5SAndroid Build Coastguard Worker         const BlendState &blendState = state.getBlendState();
4316*8975f5c5SAndroid Build Coastguard Worker         if (!blendState.colorMaskRed || !blendState.colorMaskGreen || !blendState.colorMaskBlue)
4317*8975f5c5SAndroid Build Coastguard Worker         {
4318*8975f5c5SAndroid Build Coastguard Worker             // When rendering into a YUV framebuffer, the color mask must have r g and b set to
4319*8975f5c5SAndroid Build Coastguard Worker             // true.
4320*8975f5c5SAndroid Build Coastguard Worker             return kInvalidColorMaskForYUV;
4321*8975f5c5SAndroid Build Coastguard Worker         }
4322*8975f5c5SAndroid Build Coastguard Worker 
4323*8975f5c5SAndroid Build Coastguard Worker         if (blendState.blend)
4324*8975f5c5SAndroid Build Coastguard Worker         {
4325*8975f5c5SAndroid Build Coastguard Worker             // When rendering into a YUV framebuffer, blending must be disabled.
4326*8975f5c5SAndroid Build Coastguard Worker             return kInvalidBlendStateForYUV;
4327*8975f5c5SAndroid Build Coastguard Worker         }
4328*8975f5c5SAndroid Build Coastguard Worker     }
4329*8975f5c5SAndroid Build Coastguard Worker     else
4330*8975f5c5SAndroid Build Coastguard Worker     {
4331*8975f5c5SAndroid Build Coastguard Worker         if (framebuffer->hasExternalTextureAttachment())
4332*8975f5c5SAndroid Build Coastguard Worker         {
4333*8975f5c5SAndroid Build Coastguard Worker             // It is an error to render into an external texture that is not YUV.
4334*8975f5c5SAndroid Build Coastguard Worker             return kExternalTextureAttachmentNotYUV;
4335*8975f5c5SAndroid Build Coastguard Worker         }
4336*8975f5c5SAndroid Build Coastguard Worker     }
4337*8975f5c5SAndroid Build Coastguard Worker 
4338*8975f5c5SAndroid Build Coastguard Worker     // Advanced blend equation can only be enabled for a single render target.
4339*8975f5c5SAndroid Build Coastguard Worker     const BlendStateExt &blendStateExt = state.getBlendStateExt();
4340*8975f5c5SAndroid Build Coastguard Worker     if (blendStateExt.getUsesAdvancedBlendEquationMask().any())
4341*8975f5c5SAndroid Build Coastguard Worker     {
4342*8975f5c5SAndroid Build Coastguard Worker         const size_t drawBufferCount            = framebuffer->getDrawbufferStateCount();
4343*8975f5c5SAndroid Build Coastguard Worker         uint32_t advancedBlendRenderTargetCount = 0;
4344*8975f5c5SAndroid Build Coastguard Worker 
4345*8975f5c5SAndroid Build Coastguard Worker         for (size_t drawBufferIndex : blendStateExt.getUsesAdvancedBlendEquationMask())
4346*8975f5c5SAndroid Build Coastguard Worker         {
4347*8975f5c5SAndroid Build Coastguard Worker             if (drawBufferIndex < drawBufferCount &&
4348*8975f5c5SAndroid Build Coastguard Worker                 framebuffer->getDrawBufferState(drawBufferIndex) != GL_NONE &&
4349*8975f5c5SAndroid Build Coastguard Worker                 blendStateExt.getEnabledMask().test(drawBufferIndex) &&
4350*8975f5c5SAndroid Build Coastguard Worker                 blendStateExt.getUsesAdvancedBlendEquationMask().test(drawBufferIndex))
4351*8975f5c5SAndroid Build Coastguard Worker             {
4352*8975f5c5SAndroid Build Coastguard Worker                 ++advancedBlendRenderTargetCount;
4353*8975f5c5SAndroid Build Coastguard Worker             }
4354*8975f5c5SAndroid Build Coastguard Worker         }
4355*8975f5c5SAndroid Build Coastguard Worker 
4356*8975f5c5SAndroid Build Coastguard Worker         if (advancedBlendRenderTargetCount > 1)
4357*8975f5c5SAndroid Build Coastguard Worker         {
4358*8975f5c5SAndroid Build Coastguard Worker             return kAdvancedBlendEquationWithMRT;
4359*8975f5c5SAndroid Build Coastguard Worker         }
4360*8975f5c5SAndroid Build Coastguard Worker     }
4361*8975f5c5SAndroid Build Coastguard Worker 
4362*8975f5c5SAndroid Build Coastguard Worker     // Dual-source blending functions limit the number of supported draw buffers.
4363*8975f5c5SAndroid Build Coastguard Worker     if (blendStateExt.getUsesExtendedBlendFactorMask().any())
4364*8975f5c5SAndroid Build Coastguard Worker     {
4365*8975f5c5SAndroid Build Coastguard Worker         // Imply the strictest spec interpretation to pass on all OpenGL drivers:
4366*8975f5c5SAndroid Build Coastguard Worker         // dual-source blending is considered active if the blend state contains
4367*8975f5c5SAndroid Build Coastguard Worker         // any SRC1 factor no matter what.
4368*8975f5c5SAndroid Build Coastguard Worker         const size_t drawBufferCount = framebuffer->getDrawbufferStateCount();
4369*8975f5c5SAndroid Build Coastguard Worker         for (size_t drawBufferIndex = context->getCaps().maxDualSourceDrawBuffers;
4370*8975f5c5SAndroid Build Coastguard Worker              drawBufferIndex < drawBufferCount; ++drawBufferIndex)
4371*8975f5c5SAndroid Build Coastguard Worker         {
4372*8975f5c5SAndroid Build Coastguard Worker             if (framebuffer->getDrawBufferState(drawBufferIndex) != GL_NONE)
4373*8975f5c5SAndroid Build Coastguard Worker             {
4374*8975f5c5SAndroid Build Coastguard Worker                 return kDualSourceBlendingDrawBuffersLimit;
4375*8975f5c5SAndroid Build Coastguard Worker             }
4376*8975f5c5SAndroid Build Coastguard Worker         }
4377*8975f5c5SAndroid Build Coastguard Worker     }
4378*8975f5c5SAndroid Build Coastguard Worker 
4379*8975f5c5SAndroid Build Coastguard Worker     if (context->getStateCache().hasAnyEnabledClientAttrib())
4380*8975f5c5SAndroid Build Coastguard Worker     {
4381*8975f5c5SAndroid Build Coastguard Worker         if (extensions.webglCompatibilityANGLE || !state.areClientArraysEnabled())
4382*8975f5c5SAndroid Build Coastguard Worker         {
4383*8975f5c5SAndroid Build Coastguard Worker             // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
4384*8975f5c5SAndroid Build Coastguard Worker             // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
4385*8975f5c5SAndroid Build Coastguard Worker             // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
4386*8975f5c5SAndroid Build Coastguard Worker             // to drawArrays or drawElements will generate an INVALID_OPERATION error.
4387*8975f5c5SAndroid Build Coastguard Worker             return kVertexArrayNoBuffer;
4388*8975f5c5SAndroid Build Coastguard Worker         }
4389*8975f5c5SAndroid Build Coastguard Worker 
4390*8975f5c5SAndroid Build Coastguard Worker         if (state.getVertexArray()->hasEnabledNullPointerClientArray())
4391*8975f5c5SAndroid Build Coastguard Worker         {
4392*8975f5c5SAndroid Build Coastguard Worker             // This is an application error that would normally result in a crash, but we catch it
4393*8975f5c5SAndroid Build Coastguard Worker             // and return an error
4394*8975f5c5SAndroid Build Coastguard Worker             return kVertexArrayNoBufferPointer;
4395*8975f5c5SAndroid Build Coastguard Worker         }
4396*8975f5c5SAndroid Build Coastguard Worker     }
4397*8975f5c5SAndroid Build Coastguard Worker 
4398*8975f5c5SAndroid Build Coastguard Worker     // If we are running GLES1, there is no current program.
4399*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientVersion() >= Version(2, 0))
4400*8975f5c5SAndroid Build Coastguard Worker     {
4401*8975f5c5SAndroid Build Coastguard Worker         Program *program                    = state.getLinkedProgram(context);
4402*8975f5c5SAndroid Build Coastguard Worker         ProgramPipeline *programPipeline    = state.getLinkedProgramPipeline(context);
4403*8975f5c5SAndroid Build Coastguard Worker         const ProgramExecutable *executable = state.getProgramExecutable();
4404*8975f5c5SAndroid Build Coastguard Worker 
4405*8975f5c5SAndroid Build Coastguard Worker         bool programIsYUVOutput = false;
4406*8975f5c5SAndroid Build Coastguard Worker 
4407*8975f5c5SAndroid Build Coastguard Worker         if (program)
4408*8975f5c5SAndroid Build Coastguard Worker         {
4409*8975f5c5SAndroid Build Coastguard Worker             const char *errorMsg = ValidateProgramDrawStates(context, extensions, *executable);
4410*8975f5c5SAndroid Build Coastguard Worker             if (errorMsg)
4411*8975f5c5SAndroid Build Coastguard Worker             {
4412*8975f5c5SAndroid Build Coastguard Worker                 return errorMsg;
4413*8975f5c5SAndroid Build Coastguard Worker             }
4414*8975f5c5SAndroid Build Coastguard Worker 
4415*8975f5c5SAndroid Build Coastguard Worker             programIsYUVOutput = executable->isYUVOutput();
4416*8975f5c5SAndroid Build Coastguard Worker         }
4417*8975f5c5SAndroid Build Coastguard Worker         else if (programPipeline)
4418*8975f5c5SAndroid Build Coastguard Worker         {
4419*8975f5c5SAndroid Build Coastguard Worker             const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline);
4420*8975f5c5SAndroid Build Coastguard Worker             if (errorMsg)
4421*8975f5c5SAndroid Build Coastguard Worker             {
4422*8975f5c5SAndroid Build Coastguard Worker                 return errorMsg;
4423*8975f5c5SAndroid Build Coastguard Worker             }
4424*8975f5c5SAndroid Build Coastguard Worker 
4425*8975f5c5SAndroid Build Coastguard Worker             errorMsg = ValidateProgramPipelineDrawStates(context, extensions, programPipeline);
4426*8975f5c5SAndroid Build Coastguard Worker             if (errorMsg)
4427*8975f5c5SAndroid Build Coastguard Worker             {
4428*8975f5c5SAndroid Build Coastguard Worker                 return errorMsg;
4429*8975f5c5SAndroid Build Coastguard Worker             }
4430*8975f5c5SAndroid Build Coastguard Worker 
4431*8975f5c5SAndroid Build Coastguard Worker             if (!programPipeline->isLinked())
4432*8975f5c5SAndroid Build Coastguard Worker             {
4433*8975f5c5SAndroid Build Coastguard Worker                 return kProgramPipelineLinkFailed;
4434*8975f5c5SAndroid Build Coastguard Worker             }
4435*8975f5c5SAndroid Build Coastguard Worker 
4436*8975f5c5SAndroid Build Coastguard Worker             programIsYUVOutput = executable->isYUVOutput();
4437*8975f5c5SAndroid Build Coastguard Worker         }
4438*8975f5c5SAndroid Build Coastguard Worker 
4439*8975f5c5SAndroid Build Coastguard Worker         if (executable)
4440*8975f5c5SAndroid Build Coastguard Worker         {
4441*8975f5c5SAndroid Build Coastguard Worker             if (!executable->validateSamplers(context->getCaps()))
4442*8975f5c5SAndroid Build Coastguard Worker             {
4443*8975f5c5SAndroid Build Coastguard Worker                 return kTextureTypeConflict;
4444*8975f5c5SAndroid Build Coastguard Worker             }
4445*8975f5c5SAndroid Build Coastguard Worker 
4446*8975f5c5SAndroid Build Coastguard Worker             if (executable->hasLinkedTessellationShader())
4447*8975f5c5SAndroid Build Coastguard Worker             {
4448*8975f5c5SAndroid Build Coastguard Worker                 if (!executable->hasLinkedShaderStage(ShaderType::Vertex))
4449*8975f5c5SAndroid Build Coastguard Worker                 {
4450*8975f5c5SAndroid Build Coastguard Worker                     return kTessellationShaderRequiresVertexShader;
4451*8975f5c5SAndroid Build Coastguard Worker                 }
4452*8975f5c5SAndroid Build Coastguard Worker 
4453*8975f5c5SAndroid Build Coastguard Worker                 if (!executable->hasLinkedShaderStage(ShaderType::TessControl) ||
4454*8975f5c5SAndroid Build Coastguard Worker                     !executable->hasLinkedShaderStage(ShaderType::TessEvaluation))
4455*8975f5c5SAndroid Build Coastguard Worker                 {
4456*8975f5c5SAndroid Build Coastguard Worker                     return kTessellationShaderRequiresBothControlAndEvaluation;
4457*8975f5c5SAndroid Build Coastguard Worker                 }
4458*8975f5c5SAndroid Build Coastguard Worker             }
4459*8975f5c5SAndroid Build Coastguard Worker 
4460*8975f5c5SAndroid Build Coastguard Worker             if (state.isTransformFeedbackActive())
4461*8975f5c5SAndroid Build Coastguard Worker             {
4462*8975f5c5SAndroid Build Coastguard Worker                 if (!ValidateProgramExecutableXFBBuffersPresent(context, executable))
4463*8975f5c5SAndroid Build Coastguard Worker                 {
4464*8975f5c5SAndroid Build Coastguard Worker                     return kTransformFeedbackBufferMissing;
4465*8975f5c5SAndroid Build Coastguard Worker                 }
4466*8975f5c5SAndroid Build Coastguard Worker             }
4467*8975f5c5SAndroid Build Coastguard Worker         }
4468*8975f5c5SAndroid Build Coastguard Worker 
4469*8975f5c5SAndroid Build Coastguard Worker         if (programIsYUVOutput != framebufferIsYUV)
4470*8975f5c5SAndroid Build Coastguard Worker         {
4471*8975f5c5SAndroid Build Coastguard Worker             // Both the program and framebuffer must match in YUV output state.
4472*8975f5c5SAndroid Build Coastguard Worker             return kYUVOutputMissmatch;
4473*8975f5c5SAndroid Build Coastguard Worker         }
4474*8975f5c5SAndroid Build Coastguard Worker 
4475*8975f5c5SAndroid Build Coastguard Worker         if (!state.validateSamplerFormats())
4476*8975f5c5SAndroid Build Coastguard Worker         {
4477*8975f5c5SAndroid Build Coastguard Worker             return kSamplerFormatMismatch;
4478*8975f5c5SAndroid Build Coastguard Worker         }
4479*8975f5c5SAndroid Build Coastguard Worker 
4480*8975f5c5SAndroid Build Coastguard Worker         // Do some additional WebGL-specific validation
4481*8975f5c5SAndroid Build Coastguard Worker         if (extensions.webglCompatibilityANGLE)
4482*8975f5c5SAndroid Build Coastguard Worker         {
4483*8975f5c5SAndroid Build Coastguard Worker             const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
4484*8975f5c5SAndroid Build Coastguard Worker             if (state.isTransformFeedbackActive() &&
4485*8975f5c5SAndroid Build Coastguard Worker                 transformFeedbackObject->buffersBoundForOtherUseInWebGL())
4486*8975f5c5SAndroid Build Coastguard Worker             {
4487*8975f5c5SAndroid Build Coastguard Worker                 return kTransformFeedbackBufferDoubleBound;
4488*8975f5c5SAndroid Build Coastguard Worker             }
4489*8975f5c5SAndroid Build Coastguard Worker 
4490*8975f5c5SAndroid Build Coastguard Worker             // Detect rendering feedback loops for WebGL.
4491*8975f5c5SAndroid Build Coastguard Worker             if (framebuffer->formsRenderingFeedbackLoopWith(context))
4492*8975f5c5SAndroid Build Coastguard Worker             {
4493*8975f5c5SAndroid Build Coastguard Worker                 return kFeedbackLoop;
4494*8975f5c5SAndroid Build Coastguard Worker             }
4495*8975f5c5SAndroid Build Coastguard Worker 
4496*8975f5c5SAndroid Build Coastguard Worker             // Detect that the vertex shader input types match the attribute types
4497*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateVertexShaderAttributeTypeMatch(context))
4498*8975f5c5SAndroid Build Coastguard Worker             {
4499*8975f5c5SAndroid Build Coastguard Worker                 return kVertexShaderTypeMismatch;
4500*8975f5c5SAndroid Build Coastguard Worker             }
4501*8975f5c5SAndroid Build Coastguard Worker 
4502*8975f5c5SAndroid Build Coastguard Worker             if (!context->getState().getRasterizerState().rasterizerDiscard &&
4503*8975f5c5SAndroid Build Coastguard Worker                 !context->getState().allActiveDrawBufferChannelsMasked())
4504*8975f5c5SAndroid Build Coastguard Worker             {
4505*8975f5c5SAndroid Build Coastguard Worker                 // Detect that if there's active color buffer without fragment shader output
4506*8975f5c5SAndroid Build Coastguard Worker                 if (!ValidateFragmentShaderColorBufferMaskMatch(context))
4507*8975f5c5SAndroid Build Coastguard Worker                 {
4508*8975f5c5SAndroid Build Coastguard Worker                     return kDrawBufferMaskMismatch;
4509*8975f5c5SAndroid Build Coastguard Worker                 }
4510*8975f5c5SAndroid Build Coastguard Worker 
4511*8975f5c5SAndroid Build Coastguard Worker                 // Detect that the color buffer types match the fragment shader output types
4512*8975f5c5SAndroid Build Coastguard Worker                 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
4513*8975f5c5SAndroid Build Coastguard Worker                 {
4514*8975f5c5SAndroid Build Coastguard Worker                     return kDrawBufferTypeMismatch;
4515*8975f5c5SAndroid Build Coastguard Worker                 }
4516*8975f5c5SAndroid Build Coastguard Worker             }
4517*8975f5c5SAndroid Build Coastguard Worker 
4518*8975f5c5SAndroid Build Coastguard Worker             const VertexArray *vao = context->getState().getVertexArray();
4519*8975f5c5SAndroid Build Coastguard Worker             if (vao->hasTransformFeedbackBindingConflict(context))
4520*8975f5c5SAndroid Build Coastguard Worker             {
4521*8975f5c5SAndroid Build Coastguard Worker                 return kVertexBufferBoundForTransformFeedback;
4522*8975f5c5SAndroid Build Coastguard Worker             }
4523*8975f5c5SAndroid Build Coastguard Worker 
4524*8975f5c5SAndroid Build Coastguard Worker             // Validate that we are rendering with a linked program.
4525*8975f5c5SAndroid Build Coastguard Worker             if (!program->isLinked())
4526*8975f5c5SAndroid Build Coastguard Worker             {
4527*8975f5c5SAndroid Build Coastguard Worker                 return kProgramNotLinked;
4528*8975f5c5SAndroid Build Coastguard Worker             }
4529*8975f5c5SAndroid Build Coastguard Worker         }
4530*8975f5c5SAndroid Build Coastguard Worker 
4531*8975f5c5SAndroid Build Coastguard Worker         // The QCOM_framebuffer_foveated spec:
4532*8975f5c5SAndroid Build Coastguard Worker         if (framebuffer->isFoveationEnabled())
4533*8975f5c5SAndroid Build Coastguard Worker         {
4534*8975f5c5SAndroid Build Coastguard Worker             ASSERT(extensions.framebufferFoveatedQCOM);
4535*8975f5c5SAndroid Build Coastguard Worker 
4536*8975f5c5SAndroid Build Coastguard Worker             //   INVALID_OPERATION is generated if a rendering command is issued and the
4537*8975f5c5SAndroid Build Coastguard Worker             //   current bound program uses tessellation or geometry shaders.
4538*8975f5c5SAndroid Build Coastguard Worker             if (executable->hasLinkedShaderStage(gl::ShaderType::Geometry) ||
4539*8975f5c5SAndroid Build Coastguard Worker                 executable->hasLinkedShaderStage(gl::ShaderType::TessControl) ||
4540*8975f5c5SAndroid Build Coastguard Worker                 executable->hasLinkedShaderStage(gl::ShaderType::TessEvaluation))
4541*8975f5c5SAndroid Build Coastguard Worker             {
4542*8975f5c5SAndroid Build Coastguard Worker                 return err::kGeometryOrTessellationShaderBoundForFoveatedDraw;
4543*8975f5c5SAndroid Build Coastguard Worker             }
4544*8975f5c5SAndroid Build Coastguard Worker 
4545*8975f5c5SAndroid Build Coastguard Worker             // INVALID_OPERATION is generated by any API call which causes a framebuffer
4546*8975f5c5SAndroid Build Coastguard Worker             // attachment to be written to if the framebuffer attachments have changed for
4547*8975f5c5SAndroid Build Coastguard Worker             // a foveated fbo.
4548*8975f5c5SAndroid Build Coastguard Worker             if (framebuffer->hasAnyAttachmentChanged())
4549*8975f5c5SAndroid Build Coastguard Worker             {
4550*8975f5c5SAndroid Build Coastguard Worker                 return err::kFramebufferFoveationAttachmentChanged;
4551*8975f5c5SAndroid Build Coastguard Worker             }
4552*8975f5c5SAndroid Build Coastguard Worker         }
4553*8975f5c5SAndroid Build Coastguard Worker     }
4554*8975f5c5SAndroid Build Coastguard Worker 
4555*8975f5c5SAndroid Build Coastguard Worker     *outErrorCode = GL_NO_ERROR;
4556*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
4557*8975f5c5SAndroid Build Coastguard Worker }
4558*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramPipeline(const Context * context)4559*8975f5c5SAndroid Build Coastguard Worker const char *ValidateProgramPipeline(const Context *context)
4560*8975f5c5SAndroid Build Coastguard Worker {
4561*8975f5c5SAndroid Build Coastguard Worker     const State &state = context->getState();
4562*8975f5c5SAndroid Build Coastguard Worker     // If we are running GLES1, there is no current program.
4563*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientVersion() >= Version(2, 0))
4564*8975f5c5SAndroid Build Coastguard Worker     {
4565*8975f5c5SAndroid Build Coastguard Worker         ProgramPipeline *programPipeline = state.getProgramPipeline();
4566*8975f5c5SAndroid Build Coastguard Worker         if (programPipeline)
4567*8975f5c5SAndroid Build Coastguard Worker         {
4568*8975f5c5SAndroid Build Coastguard Worker             const char *errorMsg = ValidateProgramPipelineAttachedPrograms(programPipeline);
4569*8975f5c5SAndroid Build Coastguard Worker             if (errorMsg)
4570*8975f5c5SAndroid Build Coastguard Worker             {
4571*8975f5c5SAndroid Build Coastguard Worker                 return errorMsg;
4572*8975f5c5SAndroid Build Coastguard Worker             }
4573*8975f5c5SAndroid Build Coastguard Worker         }
4574*8975f5c5SAndroid Build Coastguard Worker     }
4575*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
4576*8975f5c5SAndroid Build Coastguard Worker }
4577*8975f5c5SAndroid Build Coastguard Worker 
RecordDrawModeError(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode)4578*8975f5c5SAndroid Build Coastguard Worker void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode)
4579*8975f5c5SAndroid Build Coastguard Worker {
4580*8975f5c5SAndroid Build Coastguard Worker     const State &state                      = context->getState();
4581*8975f5c5SAndroid Build Coastguard Worker     TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
4582*8975f5c5SAndroid Build Coastguard Worker     if (state.isTransformFeedbackActiveUnpaused())
4583*8975f5c5SAndroid Build Coastguard Worker     {
4584*8975f5c5SAndroid Build Coastguard Worker         if (!ValidateTransformFeedbackPrimitiveMode(context, entryPoint,
4585*8975f5c5SAndroid Build Coastguard Worker                                                     curTransformFeedback->getPrimitiveMode(), mode))
4586*8975f5c5SAndroid Build Coastguard Worker         {
4587*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
4588*8975f5c5SAndroid Build Coastguard Worker             return;
4589*8975f5c5SAndroid Build Coastguard Worker         }
4590*8975f5c5SAndroid Build Coastguard Worker     }
4591*8975f5c5SAndroid Build Coastguard Worker 
4592*8975f5c5SAndroid Build Coastguard Worker     const Extensions &extensions = context->getExtensions();
4593*8975f5c5SAndroid Build Coastguard Worker 
4594*8975f5c5SAndroid Build Coastguard Worker     switch (mode)
4595*8975f5c5SAndroid Build Coastguard Worker     {
4596*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Points:
4597*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Lines:
4598*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineLoop:
4599*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineStrip:
4600*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Triangles:
4601*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleStrip:
4602*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleFan:
4603*8975f5c5SAndroid Build Coastguard Worker             break;
4604*8975f5c5SAndroid Build Coastguard Worker 
4605*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LinesAdjacency:
4606*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::LineStripAdjacency:
4607*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TrianglesAdjacency:
4608*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::TriangleStripAdjacency:
4609*8975f5c5SAndroid Build Coastguard Worker             if (!extensions.geometryShaderAny() && context->getClientVersion() < ES_3_2)
4610*8975f5c5SAndroid Build Coastguard Worker             {
4611*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
4612*8975f5c5SAndroid Build Coastguard Worker                 return;
4613*8975f5c5SAndroid Build Coastguard Worker             }
4614*8975f5c5SAndroid Build Coastguard Worker             break;
4615*8975f5c5SAndroid Build Coastguard Worker 
4616*8975f5c5SAndroid Build Coastguard Worker         case PrimitiveMode::Patches:
4617*8975f5c5SAndroid Build Coastguard Worker             if (!extensions.tessellationShaderAny() && context->getClientVersion() < ES_3_2)
4618*8975f5c5SAndroid Build Coastguard Worker             {
4619*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTessellationShaderEXTNotEnabled);
4620*8975f5c5SAndroid Build Coastguard Worker                 return;
4621*8975f5c5SAndroid Build Coastguard Worker             }
4622*8975f5c5SAndroid Build Coastguard Worker             break;
4623*8975f5c5SAndroid Build Coastguard Worker 
4624*8975f5c5SAndroid Build Coastguard Worker         default:
4625*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDrawMode);
4626*8975f5c5SAndroid Build Coastguard Worker             return;
4627*8975f5c5SAndroid Build Coastguard Worker     }
4628*8975f5c5SAndroid Build Coastguard Worker 
4629*8975f5c5SAndroid Build Coastguard Worker     // If we are running GLES1, there is no current program.
4630*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientVersion() >= Version(2, 0))
4631*8975f5c5SAndroid Build Coastguard Worker     {
4632*8975f5c5SAndroid Build Coastguard Worker         const ProgramExecutable *executable = state.getProgramExecutable();
4633*8975f5c5SAndroid Build Coastguard Worker         ASSERT(executable);
4634*8975f5c5SAndroid Build Coastguard Worker 
4635*8975f5c5SAndroid Build Coastguard Worker         // Do geometry shader specific validations
4636*8975f5c5SAndroid Build Coastguard Worker         if (executable->hasLinkedShaderStage(ShaderType::Geometry))
4637*8975f5c5SAndroid Build Coastguard Worker         {
4638*8975f5c5SAndroid Build Coastguard Worker             if (!IsCompatibleDrawModeWithGeometryShader(
4639*8975f5c5SAndroid Build Coastguard Worker                     mode, executable->getGeometryShaderInputPrimitiveType()))
4640*8975f5c5SAndroid Build Coastguard Worker             {
4641*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
4642*8975f5c5SAndroid Build Coastguard Worker                                        kIncompatibleDrawModeAgainstGeometryShader);
4643*8975f5c5SAndroid Build Coastguard Worker                 return;
4644*8975f5c5SAndroid Build Coastguard Worker             }
4645*8975f5c5SAndroid Build Coastguard Worker         }
4646*8975f5c5SAndroid Build Coastguard Worker 
4647*8975f5c5SAndroid Build Coastguard Worker         if (executable->hasLinkedTessellationShader() && mode != PrimitiveMode::Patches)
4648*8975f5c5SAndroid Build Coastguard Worker         {
4649*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
4650*8975f5c5SAndroid Build Coastguard Worker                                    kIncompatibleDrawModeWithTessellationShader);
4651*8975f5c5SAndroid Build Coastguard Worker             return;
4652*8975f5c5SAndroid Build Coastguard Worker         }
4653*8975f5c5SAndroid Build Coastguard Worker 
4654*8975f5c5SAndroid Build Coastguard Worker         if (!executable->hasLinkedTessellationShader() && mode == PrimitiveMode::Patches)
4655*8975f5c5SAndroid Build Coastguard Worker         {
4656*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
4657*8975f5c5SAndroid Build Coastguard Worker                                    kIncompatibleDrawModeWithoutTessellationShader);
4658*8975f5c5SAndroid Build Coastguard Worker             return;
4659*8975f5c5SAndroid Build Coastguard Worker         }
4660*8975f5c5SAndroid Build Coastguard Worker     }
4661*8975f5c5SAndroid Build Coastguard Worker 
4662*8975f5c5SAndroid Build Coastguard Worker     // An error should be recorded.
4663*8975f5c5SAndroid Build Coastguard Worker     UNREACHABLE();
4664*8975f5c5SAndroid Build Coastguard Worker }
4665*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawArraysInstancedANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)4666*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawArraysInstancedANGLE(const Context *context,
4667*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
4668*8975f5c5SAndroid Build Coastguard Worker                                       PrimitiveMode mode,
4669*8975f5c5SAndroid Build Coastguard Worker                                       GLint first,
4670*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei count,
4671*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei primcount)
4672*8975f5c5SAndroid Build Coastguard Worker {
4673*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().instancedArraysANGLE)
4674*8975f5c5SAndroid Build Coastguard Worker     {
4675*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4676*8975f5c5SAndroid Build Coastguard Worker         return false;
4677*8975f5c5SAndroid Build Coastguard Worker     }
4678*8975f5c5SAndroid Build Coastguard Worker 
4679*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount, 0))
4680*8975f5c5SAndroid Build Coastguard Worker     {
4681*8975f5c5SAndroid Build Coastguard Worker         return false;
4682*8975f5c5SAndroid Build Coastguard Worker     }
4683*8975f5c5SAndroid Build Coastguard Worker 
4684*8975f5c5SAndroid Build Coastguard Worker     return ValidateDrawInstancedANGLE(context, entryPoint);
4685*8975f5c5SAndroid Build Coastguard Worker }
4686*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawArraysInstancedEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)4687*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawArraysInstancedEXT(const Context *context,
4688*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
4689*8975f5c5SAndroid Build Coastguard Worker                                     PrimitiveMode mode,
4690*8975f5c5SAndroid Build Coastguard Worker                                     GLint first,
4691*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei count,
4692*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei primcount)
4693*8975f5c5SAndroid Build Coastguard Worker {
4694*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().instancedArraysEXT)
4695*8975f5c5SAndroid Build Coastguard Worker     {
4696*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4697*8975f5c5SAndroid Build Coastguard Worker         return false;
4698*8975f5c5SAndroid Build Coastguard Worker     }
4699*8975f5c5SAndroid Build Coastguard Worker 
4700*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount, 0))
4701*8975f5c5SAndroid Build Coastguard Worker     {
4702*8975f5c5SAndroid Build Coastguard Worker         return false;
4703*8975f5c5SAndroid Build Coastguard Worker     }
4704*8975f5c5SAndroid Build Coastguard Worker 
4705*8975f5c5SAndroid Build Coastguard Worker     return true;
4706*8975f5c5SAndroid Build Coastguard Worker }
4707*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawElementsStates(const Context * context)4708*8975f5c5SAndroid Build Coastguard Worker const char *ValidateDrawElementsStates(const Context *context)
4709*8975f5c5SAndroid Build Coastguard Worker {
4710*8975f5c5SAndroid Build Coastguard Worker     const State &state = context->getState();
4711*8975f5c5SAndroid Build Coastguard Worker 
4712*8975f5c5SAndroid Build Coastguard Worker     if (context->getStateCache().isTransformFeedbackActiveUnpaused())
4713*8975f5c5SAndroid Build Coastguard Worker     {
4714*8975f5c5SAndroid Build Coastguard Worker         // EXT_geometry_shader allows transform feedback to work with all draw commands.
4715*8975f5c5SAndroid Build Coastguard Worker         // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
4716*8975f5c5SAndroid Build Coastguard Worker         if (!context->getExtensions().geometryShaderAny() && context->getClientVersion() < ES_3_2)
4717*8975f5c5SAndroid Build Coastguard Worker         {
4718*8975f5c5SAndroid Build Coastguard Worker             // It is an invalid operation to call DrawElements, DrawRangeElements or
4719*8975f5c5SAndroid Build Coastguard Worker             // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
4720*8975f5c5SAndroid Build Coastguard Worker             // 86)
4721*8975f5c5SAndroid Build Coastguard Worker             return kUnsupportedDrawModeForTransformFeedback;
4722*8975f5c5SAndroid Build Coastguard Worker         }
4723*8975f5c5SAndroid Build Coastguard Worker     }
4724*8975f5c5SAndroid Build Coastguard Worker 
4725*8975f5c5SAndroid Build Coastguard Worker     const VertexArray *vao     = state.getVertexArray();
4726*8975f5c5SAndroid Build Coastguard Worker     Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
4727*8975f5c5SAndroid Build Coastguard Worker 
4728*8975f5c5SAndroid Build Coastguard Worker     if (elementArrayBuffer)
4729*8975f5c5SAndroid Build Coastguard Worker     {
4730*8975f5c5SAndroid Build Coastguard Worker         if (elementArrayBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
4731*8975f5c5SAndroid Build Coastguard Worker         {
4732*8975f5c5SAndroid Build Coastguard Worker             return kElementArrayBufferBoundForTransformFeedback;
4733*8975f5c5SAndroid Build Coastguard Worker         }
4734*8975f5c5SAndroid Build Coastguard Worker         if (elementArrayBuffer->isMapped() &&
4735*8975f5c5SAndroid Build Coastguard Worker             (!elementArrayBuffer->isImmutable() ||
4736*8975f5c5SAndroid Build Coastguard Worker              (elementArrayBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) == 0))
4737*8975f5c5SAndroid Build Coastguard Worker         {
4738*8975f5c5SAndroid Build Coastguard Worker             return kBufferMapped;
4739*8975f5c5SAndroid Build Coastguard Worker         }
4740*8975f5c5SAndroid Build Coastguard Worker     }
4741*8975f5c5SAndroid Build Coastguard Worker     else
4742*8975f5c5SAndroid Build Coastguard Worker     {
4743*8975f5c5SAndroid Build Coastguard Worker         // [WebGL 1.0] Section 6.2 No Client Side Arrays
4744*8975f5c5SAndroid Build Coastguard Worker         // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
4745*8975f5c5SAndroid Build Coastguard Worker         // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
4746*8975f5c5SAndroid Build Coastguard Worker         if (!context->getState().areClientArraysEnabled() || context->isWebGL())
4747*8975f5c5SAndroid Build Coastguard Worker         {
4748*8975f5c5SAndroid Build Coastguard Worker             return kMustHaveElementArrayBinding;
4749*8975f5c5SAndroid Build Coastguard Worker         }
4750*8975f5c5SAndroid Build Coastguard Worker     }
4751*8975f5c5SAndroid Build Coastguard Worker 
4752*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
4753*8975f5c5SAndroid Build Coastguard Worker }
4754*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawElementsInstancedANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount)4755*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawElementsInstancedANGLE(const Context *context,
4756*8975f5c5SAndroid Build Coastguard Worker                                         angle::EntryPoint entryPoint,
4757*8975f5c5SAndroid Build Coastguard Worker                                         PrimitiveMode mode,
4758*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei count,
4759*8975f5c5SAndroid Build Coastguard Worker                                         DrawElementsType type,
4760*8975f5c5SAndroid Build Coastguard Worker                                         const void *indices,
4761*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei primcount)
4762*8975f5c5SAndroid Build Coastguard Worker {
4763*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().instancedArraysANGLE)
4764*8975f5c5SAndroid Build Coastguard Worker     {
4765*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4766*8975f5c5SAndroid Build Coastguard Worker         return false;
4767*8975f5c5SAndroid Build Coastguard Worker     }
4768*8975f5c5SAndroid Build Coastguard Worker 
4769*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
4770*8975f5c5SAndroid Build Coastguard Worker                                            primcount, 0))
4771*8975f5c5SAndroid Build Coastguard Worker     {
4772*8975f5c5SAndroid Build Coastguard Worker         return false;
4773*8975f5c5SAndroid Build Coastguard Worker     }
4774*8975f5c5SAndroid Build Coastguard Worker 
4775*8975f5c5SAndroid Build Coastguard Worker     return ValidateDrawInstancedANGLE(context, entryPoint);
4776*8975f5c5SAndroid Build Coastguard Worker }
4777*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawElementsInstancedEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount)4778*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawElementsInstancedEXT(const Context *context,
4779*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
4780*8975f5c5SAndroid Build Coastguard Worker                                       PrimitiveMode mode,
4781*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei count,
4782*8975f5c5SAndroid Build Coastguard Worker                                       DrawElementsType type,
4783*8975f5c5SAndroid Build Coastguard Worker                                       const void *indices,
4784*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei primcount)
4785*8975f5c5SAndroid Build Coastguard Worker {
4786*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().instancedArraysEXT)
4787*8975f5c5SAndroid Build Coastguard Worker     {
4788*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4789*8975f5c5SAndroid Build Coastguard Worker         return false;
4790*8975f5c5SAndroid Build Coastguard Worker     }
4791*8975f5c5SAndroid Build Coastguard Worker 
4792*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
4793*8975f5c5SAndroid Build Coastguard Worker                                            primcount, 0))
4794*8975f5c5SAndroid Build Coastguard Worker     {
4795*8975f5c5SAndroid Build Coastguard Worker         return false;
4796*8975f5c5SAndroid Build Coastguard Worker     }
4797*8975f5c5SAndroid Build Coastguard Worker 
4798*8975f5c5SAndroid Build Coastguard Worker     return true;
4799*8975f5c5SAndroid Build Coastguard Worker }
4800*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetUniformBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location)4801*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformBase(const Context *context,
4802*8975f5c5SAndroid Build Coastguard Worker                             angle::EntryPoint entryPoint,
4803*8975f5c5SAndroid Build Coastguard Worker                             ShaderProgramID program,
4804*8975f5c5SAndroid Build Coastguard Worker                             UniformLocation location)
4805*8975f5c5SAndroid Build Coastguard Worker {
4806*8975f5c5SAndroid Build Coastguard Worker     if (program.value == 0)
4807*8975f5c5SAndroid Build Coastguard Worker     {
4808*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
4809*8975f5c5SAndroid Build Coastguard Worker         return false;
4810*8975f5c5SAndroid Build Coastguard Worker     }
4811*8975f5c5SAndroid Build Coastguard Worker 
4812*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = GetValidProgram(context, entryPoint, program);
4813*8975f5c5SAndroid Build Coastguard Worker     if (!programObject)
4814*8975f5c5SAndroid Build Coastguard Worker     {
4815*8975f5c5SAndroid Build Coastguard Worker         return false;
4816*8975f5c5SAndroid Build Coastguard Worker     }
4817*8975f5c5SAndroid Build Coastguard Worker 
4818*8975f5c5SAndroid Build Coastguard Worker     if (!programObject || !programObject->isLinked())
4819*8975f5c5SAndroid Build Coastguard Worker     {
4820*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
4821*8975f5c5SAndroid Build Coastguard Worker         return false;
4822*8975f5c5SAndroid Build Coastguard Worker     }
4823*8975f5c5SAndroid Build Coastguard Worker 
4824*8975f5c5SAndroid Build Coastguard Worker     if (!programObject->getExecutable().isValidUniformLocation(location))
4825*8975f5c5SAndroid Build Coastguard Worker     {
4826*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUniformLocation);
4827*8975f5c5SAndroid Build Coastguard Worker         return false;
4828*8975f5c5SAndroid Build Coastguard Worker     }
4829*8975f5c5SAndroid Build Coastguard Worker 
4830*8975f5c5SAndroid Build Coastguard Worker     return true;
4831*8975f5c5SAndroid Build Coastguard Worker }
4832*8975f5c5SAndroid Build Coastguard Worker 
ValidateSizedGetUniform(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,GLsizei * length)4833*8975f5c5SAndroid Build Coastguard Worker bool ValidateSizedGetUniform(const Context *context,
4834*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
4835*8975f5c5SAndroid Build Coastguard Worker                              ShaderProgramID program,
4836*8975f5c5SAndroid Build Coastguard Worker                              UniformLocation location,
4837*8975f5c5SAndroid Build Coastguard Worker                              GLsizei bufSize,
4838*8975f5c5SAndroid Build Coastguard Worker                              GLsizei *length)
4839*8975f5c5SAndroid Build Coastguard Worker {
4840*8975f5c5SAndroid Build Coastguard Worker     if (length)
4841*8975f5c5SAndroid Build Coastguard Worker     {
4842*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
4843*8975f5c5SAndroid Build Coastguard Worker     }
4844*8975f5c5SAndroid Build Coastguard Worker 
4845*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetUniformBase(context, entryPoint, program, location))
4846*8975f5c5SAndroid Build Coastguard Worker     {
4847*8975f5c5SAndroid Build Coastguard Worker         return false;
4848*8975f5c5SAndroid Build Coastguard Worker     }
4849*8975f5c5SAndroid Build Coastguard Worker 
4850*8975f5c5SAndroid Build Coastguard Worker     if (bufSize < 0)
4851*8975f5c5SAndroid Build Coastguard Worker     {
4852*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNegativeBufferSize);
4853*8975f5c5SAndroid Build Coastguard Worker         return false;
4854*8975f5c5SAndroid Build Coastguard Worker     }
4855*8975f5c5SAndroid Build Coastguard Worker 
4856*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = context->getProgramResolveLink(program);
4857*8975f5c5SAndroid Build Coastguard Worker     ASSERT(programObject);
4858*8975f5c5SAndroid Build Coastguard Worker 
4859*8975f5c5SAndroid Build Coastguard Worker     // sized queries -- ensure the provided buffer is large enough
4860*8975f5c5SAndroid Build Coastguard Worker     const LinkedUniform &uniform = programObject->getExecutable().getUniformByLocation(location);
4861*8975f5c5SAndroid Build Coastguard Worker     size_t requiredBytes         = VariableExternalSize(uniform.getType());
4862*8975f5c5SAndroid Build Coastguard Worker     if (static_cast<size_t>(bufSize) < requiredBytes)
4863*8975f5c5SAndroid Build Coastguard Worker     {
4864*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
4865*8975f5c5SAndroid Build Coastguard Worker         return false;
4866*8975f5c5SAndroid Build Coastguard Worker     }
4867*8975f5c5SAndroid Build Coastguard Worker 
4868*8975f5c5SAndroid Build Coastguard Worker     if (length)
4869*8975f5c5SAndroid Build Coastguard Worker     {
4870*8975f5c5SAndroid Build Coastguard Worker         *length = VariableComponentCount(uniform.getType());
4871*8975f5c5SAndroid Build Coastguard Worker     }
4872*8975f5c5SAndroid Build Coastguard Worker     return true;
4873*8975f5c5SAndroid Build Coastguard Worker }
4874*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetnUniformfvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLfloat * params)4875*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformfvEXT(const Context *context,
4876*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
4877*8975f5c5SAndroid Build Coastguard Worker                               ShaderProgramID program,
4878*8975f5c5SAndroid Build Coastguard Worker                               UniformLocation location,
4879*8975f5c5SAndroid Build Coastguard Worker                               GLsizei bufSize,
4880*8975f5c5SAndroid Build Coastguard Worker                               const GLfloat *params)
4881*8975f5c5SAndroid Build Coastguard Worker {
4882*8975f5c5SAndroid Build Coastguard Worker     return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
4883*8975f5c5SAndroid Build Coastguard Worker }
4884*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetnUniformfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLfloat * params)4885*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformfvRobustANGLE(const Context *context,
4886*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
4887*8975f5c5SAndroid Build Coastguard Worker                                       ShaderProgramID program,
4888*8975f5c5SAndroid Build Coastguard Worker                                       UniformLocation location,
4889*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei bufSize,
4890*8975f5c5SAndroid Build Coastguard Worker                                       const GLsizei *length,
4891*8975f5c5SAndroid Build Coastguard Worker                                       const GLfloat *params)
4892*8975f5c5SAndroid Build Coastguard Worker {
4893*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
4894*8975f5c5SAndroid Build Coastguard Worker     return false;
4895*8975f5c5SAndroid Build Coastguard Worker }
4896*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetnUniformivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLint * params)4897*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformivEXT(const Context *context,
4898*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
4899*8975f5c5SAndroid Build Coastguard Worker                               ShaderProgramID program,
4900*8975f5c5SAndroid Build Coastguard Worker                               UniformLocation location,
4901*8975f5c5SAndroid Build Coastguard Worker                               GLsizei bufSize,
4902*8975f5c5SAndroid Build Coastguard Worker                               const GLint *params)
4903*8975f5c5SAndroid Build Coastguard Worker {
4904*8975f5c5SAndroid Build Coastguard Worker     return ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, nullptr);
4905*8975f5c5SAndroid Build Coastguard Worker }
4906*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetnUniformivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLint * params)4907*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformivRobustANGLE(const Context *context,
4908*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
4909*8975f5c5SAndroid Build Coastguard Worker                                       ShaderProgramID program,
4910*8975f5c5SAndroid Build Coastguard Worker                                       UniformLocation location,
4911*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei bufSize,
4912*8975f5c5SAndroid Build Coastguard Worker                                       const GLsizei *length,
4913*8975f5c5SAndroid Build Coastguard Worker                                       const GLint *params)
4914*8975f5c5SAndroid Build Coastguard Worker {
4915*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
4916*8975f5c5SAndroid Build Coastguard Worker     return false;
4917*8975f5c5SAndroid Build Coastguard Worker }
4918*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetnUniformuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLuint * params)4919*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetnUniformuivRobustANGLE(const Context *context,
4920*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
4921*8975f5c5SAndroid Build Coastguard Worker                                        ShaderProgramID program,
4922*8975f5c5SAndroid Build Coastguard Worker                                        UniformLocation location,
4923*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei bufSize,
4924*8975f5c5SAndroid Build Coastguard Worker                                        const GLsizei *length,
4925*8975f5c5SAndroid Build Coastguard Worker                                        const GLuint *params)
4926*8975f5c5SAndroid Build Coastguard Worker {
4927*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
4928*8975f5c5SAndroid Build Coastguard Worker     return false;
4929*8975f5c5SAndroid Build Coastguard Worker }
4930*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetUniformfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLfloat * params)4931*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformfvRobustANGLE(const Context *context,
4932*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
4933*8975f5c5SAndroid Build Coastguard Worker                                      ShaderProgramID program,
4934*8975f5c5SAndroid Build Coastguard Worker                                      UniformLocation location,
4935*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei bufSize,
4936*8975f5c5SAndroid Build Coastguard Worker                                      const GLsizei *length,
4937*8975f5c5SAndroid Build Coastguard Worker                                      const GLfloat *params)
4938*8975f5c5SAndroid Build Coastguard Worker {
4939*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
4940*8975f5c5SAndroid Build Coastguard Worker     {
4941*8975f5c5SAndroid Build Coastguard Worker         return false;
4942*8975f5c5SAndroid Build Coastguard Worker     }
4943*8975f5c5SAndroid Build Coastguard Worker 
4944*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
4945*8975f5c5SAndroid Build Coastguard Worker 
4946*8975f5c5SAndroid Build Coastguard Worker     // bufSize is validated in ValidateSizedGetUniform
4947*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
4948*8975f5c5SAndroid Build Coastguard Worker     {
4949*8975f5c5SAndroid Build Coastguard Worker         return false;
4950*8975f5c5SAndroid Build Coastguard Worker     }
4951*8975f5c5SAndroid Build Coastguard Worker 
4952*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
4953*8975f5c5SAndroid Build Coastguard Worker 
4954*8975f5c5SAndroid Build Coastguard Worker     return true;
4955*8975f5c5SAndroid Build Coastguard Worker }
4956*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetUniformivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLint * params)4957*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformivRobustANGLE(const Context *context,
4958*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
4959*8975f5c5SAndroid Build Coastguard Worker                                      ShaderProgramID program,
4960*8975f5c5SAndroid Build Coastguard Worker                                      UniformLocation location,
4961*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei bufSize,
4962*8975f5c5SAndroid Build Coastguard Worker                                      const GLsizei *length,
4963*8975f5c5SAndroid Build Coastguard Worker                                      const GLint *params)
4964*8975f5c5SAndroid Build Coastguard Worker {
4965*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
4966*8975f5c5SAndroid Build Coastguard Worker     {
4967*8975f5c5SAndroid Build Coastguard Worker         return false;
4968*8975f5c5SAndroid Build Coastguard Worker     }
4969*8975f5c5SAndroid Build Coastguard Worker 
4970*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
4971*8975f5c5SAndroid Build Coastguard Worker 
4972*8975f5c5SAndroid Build Coastguard Worker     // bufSize is validated in ValidateSizedGetUniform
4973*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
4974*8975f5c5SAndroid Build Coastguard Worker     {
4975*8975f5c5SAndroid Build Coastguard Worker         return false;
4976*8975f5c5SAndroid Build Coastguard Worker     }
4977*8975f5c5SAndroid Build Coastguard Worker 
4978*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
4979*8975f5c5SAndroid Build Coastguard Worker 
4980*8975f5c5SAndroid Build Coastguard Worker     return true;
4981*8975f5c5SAndroid Build Coastguard Worker }
4982*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetUniformuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,GLsizei bufSize,const GLsizei * length,const GLuint * params)4983*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetUniformuivRobustANGLE(const Context *context,
4984*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
4985*8975f5c5SAndroid Build Coastguard Worker                                       ShaderProgramID program,
4986*8975f5c5SAndroid Build Coastguard Worker                                       UniformLocation location,
4987*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei bufSize,
4988*8975f5c5SAndroid Build Coastguard Worker                                       const GLsizei *length,
4989*8975f5c5SAndroid Build Coastguard Worker                                       const GLuint *params)
4990*8975f5c5SAndroid Build Coastguard Worker {
4991*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
4992*8975f5c5SAndroid Build Coastguard Worker     {
4993*8975f5c5SAndroid Build Coastguard Worker         return false;
4994*8975f5c5SAndroid Build Coastguard Worker     }
4995*8975f5c5SAndroid Build Coastguard Worker 
4996*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() < 3)
4997*8975f5c5SAndroid Build Coastguard Worker     {
4998*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4999*8975f5c5SAndroid Build Coastguard Worker         return false;
5000*8975f5c5SAndroid Build Coastguard Worker     }
5001*8975f5c5SAndroid Build Coastguard Worker 
5002*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
5003*8975f5c5SAndroid Build Coastguard Worker 
5004*8975f5c5SAndroid Build Coastguard Worker     // bufSize is validated in ValidateSizedGetUniform
5005*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateSizedGetUniform(context, entryPoint, program, location, bufSize, &writeLength))
5006*8975f5c5SAndroid Build Coastguard Worker     {
5007*8975f5c5SAndroid Build Coastguard Worker         return false;
5008*8975f5c5SAndroid Build Coastguard Worker     }
5009*8975f5c5SAndroid Build Coastguard Worker 
5010*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
5011*8975f5c5SAndroid Build Coastguard Worker 
5012*8975f5c5SAndroid Build Coastguard Worker     return true;
5013*8975f5c5SAndroid Build Coastguard Worker }
5014*8975f5c5SAndroid Build Coastguard Worker 
ValidateDiscardFramebufferBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei numAttachments,const GLenum * attachments,bool defaultFramebuffer)5015*8975f5c5SAndroid Build Coastguard Worker bool ValidateDiscardFramebufferBase(const Context *context,
5016*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
5017*8975f5c5SAndroid Build Coastguard Worker                                     GLenum target,
5018*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei numAttachments,
5019*8975f5c5SAndroid Build Coastguard Worker                                     const GLenum *attachments,
5020*8975f5c5SAndroid Build Coastguard Worker                                     bool defaultFramebuffer)
5021*8975f5c5SAndroid Build Coastguard Worker {
5022*8975f5c5SAndroid Build Coastguard Worker     if (numAttachments < 0)
5023*8975f5c5SAndroid Build Coastguard Worker     {
5024*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeAttachments);
5025*8975f5c5SAndroid Build Coastguard Worker         return false;
5026*8975f5c5SAndroid Build Coastguard Worker     }
5027*8975f5c5SAndroid Build Coastguard Worker 
5028*8975f5c5SAndroid Build Coastguard Worker     for (GLsizei i = 0; i < numAttachments; ++i)
5029*8975f5c5SAndroid Build Coastguard Worker     {
5030*8975f5c5SAndroid Build Coastguard Worker         if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
5031*8975f5c5SAndroid Build Coastguard Worker         {
5032*8975f5c5SAndroid Build Coastguard Worker             if (defaultFramebuffer)
5033*8975f5c5SAndroid Build Coastguard Worker             {
5034*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
5035*8975f5c5SAndroid Build Coastguard Worker                 return false;
5036*8975f5c5SAndroid Build Coastguard Worker             }
5037*8975f5c5SAndroid Build Coastguard Worker 
5038*8975f5c5SAndroid Build Coastguard Worker             if (attachments[i] >=
5039*8975f5c5SAndroid Build Coastguard Worker                 GL_COLOR_ATTACHMENT0 + static_cast<GLuint>(context->getCaps().maxColorAttachments))
5040*8975f5c5SAndroid Build Coastguard Worker             {
5041*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
5042*8975f5c5SAndroid Build Coastguard Worker                 return false;
5043*8975f5c5SAndroid Build Coastguard Worker             }
5044*8975f5c5SAndroid Build Coastguard Worker         }
5045*8975f5c5SAndroid Build Coastguard Worker         else
5046*8975f5c5SAndroid Build Coastguard Worker         {
5047*8975f5c5SAndroid Build Coastguard Worker             switch (attachments[i])
5048*8975f5c5SAndroid Build Coastguard Worker             {
5049*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_ATTACHMENT:
5050*8975f5c5SAndroid Build Coastguard Worker                 case GL_STENCIL_ATTACHMENT:
5051*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_STENCIL_ATTACHMENT:
5052*8975f5c5SAndroid Build Coastguard Worker                     if (defaultFramebuffer)
5053*8975f5c5SAndroid Build Coastguard Worker                     {
5054*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
5055*8975f5c5SAndroid Build Coastguard Worker                                                kDefaultFramebufferInvalidAttachment);
5056*8975f5c5SAndroid Build Coastguard Worker                         return false;
5057*8975f5c5SAndroid Build Coastguard Worker                     }
5058*8975f5c5SAndroid Build Coastguard Worker                     break;
5059*8975f5c5SAndroid Build Coastguard Worker                 case GL_COLOR:
5060*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH:
5061*8975f5c5SAndroid Build Coastguard Worker                 case GL_STENCIL:
5062*8975f5c5SAndroid Build Coastguard Worker                     if (!defaultFramebuffer)
5063*8975f5c5SAndroid Build Coastguard Worker                     {
5064*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
5065*8975f5c5SAndroid Build Coastguard Worker                                                kDefaultFramebufferAttachmentOnUserFBO);
5066*8975f5c5SAndroid Build Coastguard Worker                         return false;
5067*8975f5c5SAndroid Build Coastguard Worker                     }
5068*8975f5c5SAndroid Build Coastguard Worker                     break;
5069*8975f5c5SAndroid Build Coastguard Worker                 default:
5070*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5071*8975f5c5SAndroid Build Coastguard Worker                     return false;
5072*8975f5c5SAndroid Build Coastguard Worker             }
5073*8975f5c5SAndroid Build Coastguard Worker         }
5074*8975f5c5SAndroid Build Coastguard Worker     }
5075*8975f5c5SAndroid Build Coastguard Worker 
5076*8975f5c5SAndroid Build Coastguard Worker     return true;
5077*8975f5c5SAndroid Build Coastguard Worker }
5078*8975f5c5SAndroid Build Coastguard Worker 
ValidateInsertEventMarkerEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei length,const char * marker)5079*8975f5c5SAndroid Build Coastguard Worker bool ValidateInsertEventMarkerEXT(const Context *context,
5080*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
5081*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei length,
5082*8975f5c5SAndroid Build Coastguard Worker                                   const char *marker)
5083*8975f5c5SAndroid Build Coastguard Worker {
5084*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().debugMarkerEXT)
5085*8975f5c5SAndroid Build Coastguard Worker     {
5086*8975f5c5SAndroid Build Coastguard Worker         // The debug marker calls should not set error state
5087*8975f5c5SAndroid Build Coastguard Worker         // However, it seems reasonable to set an error state if the extension is not enabled
5088*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5089*8975f5c5SAndroid Build Coastguard Worker         return false;
5090*8975f5c5SAndroid Build Coastguard Worker     }
5091*8975f5c5SAndroid Build Coastguard Worker 
5092*8975f5c5SAndroid Build Coastguard Worker     // Note that debug marker calls must not set error state
5093*8975f5c5SAndroid Build Coastguard Worker     if (length < 0)
5094*8975f5c5SAndroid Build Coastguard Worker     {
5095*8975f5c5SAndroid Build Coastguard Worker         return false;
5096*8975f5c5SAndroid Build Coastguard Worker     }
5097*8975f5c5SAndroid Build Coastguard Worker 
5098*8975f5c5SAndroid Build Coastguard Worker     if (marker == nullptr)
5099*8975f5c5SAndroid Build Coastguard Worker     {
5100*8975f5c5SAndroid Build Coastguard Worker         return false;
5101*8975f5c5SAndroid Build Coastguard Worker     }
5102*8975f5c5SAndroid Build Coastguard Worker 
5103*8975f5c5SAndroid Build Coastguard Worker     return true;
5104*8975f5c5SAndroid Build Coastguard Worker }
5105*8975f5c5SAndroid Build Coastguard Worker 
ValidatePushGroupMarkerEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei length,const char * marker)5106*8975f5c5SAndroid Build Coastguard Worker bool ValidatePushGroupMarkerEXT(const Context *context,
5107*8975f5c5SAndroid Build Coastguard Worker                                 angle::EntryPoint entryPoint,
5108*8975f5c5SAndroid Build Coastguard Worker                                 GLsizei length,
5109*8975f5c5SAndroid Build Coastguard Worker                                 const char *marker)
5110*8975f5c5SAndroid Build Coastguard Worker {
5111*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().debugMarkerEXT)
5112*8975f5c5SAndroid Build Coastguard Worker     {
5113*8975f5c5SAndroid Build Coastguard Worker         // The debug marker calls should not set error state
5114*8975f5c5SAndroid Build Coastguard Worker         // However, it seems reasonable to set an error state if the extension is not enabled
5115*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5116*8975f5c5SAndroid Build Coastguard Worker         return false;
5117*8975f5c5SAndroid Build Coastguard Worker     }
5118*8975f5c5SAndroid Build Coastguard Worker 
5119*8975f5c5SAndroid Build Coastguard Worker     // Note that debug marker calls must not set error state
5120*8975f5c5SAndroid Build Coastguard Worker     if (length < 0)
5121*8975f5c5SAndroid Build Coastguard Worker     {
5122*8975f5c5SAndroid Build Coastguard Worker         return false;
5123*8975f5c5SAndroid Build Coastguard Worker     }
5124*8975f5c5SAndroid Build Coastguard Worker 
5125*8975f5c5SAndroid Build Coastguard Worker     if (length > 0 && marker == nullptr)
5126*8975f5c5SAndroid Build Coastguard Worker     {
5127*8975f5c5SAndroid Build Coastguard Worker         return false;
5128*8975f5c5SAndroid Build Coastguard Worker     }
5129*8975f5c5SAndroid Build Coastguard Worker 
5130*8975f5c5SAndroid Build Coastguard Worker     return true;
5131*8975f5c5SAndroid Build Coastguard Worker }
5132*8975f5c5SAndroid Build Coastguard Worker 
ValidateEGLImageObject(const Context * context,angle::EntryPoint entryPoint,TextureType type,egl::ImageID imageID)5133*8975f5c5SAndroid Build Coastguard Worker bool ValidateEGLImageObject(const Context *context,
5134*8975f5c5SAndroid Build Coastguard Worker                             angle::EntryPoint entryPoint,
5135*8975f5c5SAndroid Build Coastguard Worker                             TextureType type,
5136*8975f5c5SAndroid Build Coastguard Worker                             egl::ImageID imageID)
5137*8975f5c5SAndroid Build Coastguard Worker {
5138*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context->getDisplay());
5139*8975f5c5SAndroid Build Coastguard Worker     if (!context->getDisplay()->isValidImage(imageID))
5140*8975f5c5SAndroid Build Coastguard Worker     {
5141*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidEGLImage);
5142*8975f5c5SAndroid Build Coastguard Worker         return false;
5143*8975f5c5SAndroid Build Coastguard Worker     }
5144*8975f5c5SAndroid Build Coastguard Worker 
5145*8975f5c5SAndroid Build Coastguard Worker     egl::Image *imageObject = context->getDisplay()->getImage(imageID);
5146*8975f5c5SAndroid Build Coastguard Worker     if (imageObject->getSamples() > 0)
5147*8975f5c5SAndroid Build Coastguard Worker     {
5148*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageCannotCreate2DMultisampled);
5149*8975f5c5SAndroid Build Coastguard Worker         return false;
5150*8975f5c5SAndroid Build Coastguard Worker     }
5151*8975f5c5SAndroid Build Coastguard Worker 
5152*8975f5c5SAndroid Build Coastguard Worker     if (!imageObject->isTexturable(context))
5153*8975f5c5SAndroid Build Coastguard Worker     {
5154*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureFormatNotSupported);
5155*8975f5c5SAndroid Build Coastguard Worker         return false;
5156*8975f5c5SAndroid Build Coastguard Worker     }
5157*8975f5c5SAndroid Build Coastguard Worker 
5158*8975f5c5SAndroid Build Coastguard Worker     // Validate source egl image and target texture are compatible
5159*8975f5c5SAndroid Build Coastguard Worker     size_t depth = static_cast<size_t>(imageObject->getExtents().depth);
5160*8975f5c5SAndroid Build Coastguard Worker     if (imageObject->isYUV() && type != TextureType::External)
5161*8975f5c5SAndroid Build Coastguard Worker     {
5162*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5163*8975f5c5SAndroid Build Coastguard Worker                                "Image is YUV, target must be TEXTURE_EXTERNAL_OES");
5164*8975f5c5SAndroid Build Coastguard Worker         return false;
5165*8975f5c5SAndroid Build Coastguard Worker     }
5166*8975f5c5SAndroid Build Coastguard Worker 
5167*8975f5c5SAndroid Build Coastguard Worker     if (depth > 1 && type != TextureType::_2DArray && type != TextureType::CubeMap &&
5168*8975f5c5SAndroid Build Coastguard Worker         type != TextureType::CubeMapArray && type != TextureType::_3D)
5169*8975f5c5SAndroid Build Coastguard Worker     {
5170*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5171*8975f5c5SAndroid Build Coastguard Worker         return false;
5172*8975f5c5SAndroid Build Coastguard Worker     }
5173*8975f5c5SAndroid Build Coastguard Worker 
5174*8975f5c5SAndroid Build Coastguard Worker     if (imageObject->isCubeMap() && type != TextureType::CubeMapArray &&
5175*8975f5c5SAndroid Build Coastguard Worker         (type != TextureType::CubeMap || depth > gl::kCubeFaceCount))
5176*8975f5c5SAndroid Build Coastguard Worker     {
5177*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5178*8975f5c5SAndroid Build Coastguard Worker         return false;
5179*8975f5c5SAndroid Build Coastguard Worker     }
5180*8975f5c5SAndroid Build Coastguard Worker 
5181*8975f5c5SAndroid Build Coastguard Worker     if (imageObject->getLevelCount() > 1 && type == TextureType::External)
5182*8975f5c5SAndroid Build Coastguard Worker     {
5183*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5184*8975f5c5SAndroid Build Coastguard Worker         return false;
5185*8975f5c5SAndroid Build Coastguard Worker     }
5186*8975f5c5SAndroid Build Coastguard Worker 
5187*8975f5c5SAndroid Build Coastguard Worker     // 3d EGLImages are currently not supported
5188*8975f5c5SAndroid Build Coastguard Worker     if (type == TextureType::_3D)
5189*8975f5c5SAndroid Build Coastguard Worker     {
5190*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageTextureTargetMismatch);
5191*8975f5c5SAndroid Build Coastguard Worker         return false;
5192*8975f5c5SAndroid Build Coastguard Worker     }
5193*8975f5c5SAndroid Build Coastguard Worker 
5194*8975f5c5SAndroid Build Coastguard Worker     if (imageObject->hasProtectedContent() && !context->getState().hasProtectedContent())
5195*8975f5c5SAndroid Build Coastguard Worker     {
5196*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5197*8975f5c5SAndroid Build Coastguard Worker                                "Mismatch between Image and Context Protected Content state");
5198*8975f5c5SAndroid Build Coastguard Worker         return false;
5199*8975f5c5SAndroid Build Coastguard Worker     }
5200*8975f5c5SAndroid Build Coastguard Worker 
5201*8975f5c5SAndroid Build Coastguard Worker     return true;
5202*8975f5c5SAndroid Build Coastguard Worker }
5203*8975f5c5SAndroid Build Coastguard Worker 
ValidateEGLImageTargetTexture2DOES(const Context * context,angle::EntryPoint entryPoint,TextureType type,egl::ImageID image)5204*8975f5c5SAndroid Build Coastguard Worker bool ValidateEGLImageTargetTexture2DOES(const Context *context,
5205*8975f5c5SAndroid Build Coastguard Worker                                         angle::EntryPoint entryPoint,
5206*8975f5c5SAndroid Build Coastguard Worker                                         TextureType type,
5207*8975f5c5SAndroid Build Coastguard Worker                                         egl::ImageID image)
5208*8975f5c5SAndroid Build Coastguard Worker {
5209*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().EGLImageOES && !context->getExtensions().EGLImageExternalOES)
5210*8975f5c5SAndroid Build Coastguard Worker     {
5211*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5212*8975f5c5SAndroid Build Coastguard Worker         return false;
5213*8975f5c5SAndroid Build Coastguard Worker     }
5214*8975f5c5SAndroid Build Coastguard Worker 
5215*8975f5c5SAndroid Build Coastguard Worker     switch (type)
5216*8975f5c5SAndroid Build Coastguard Worker     {
5217*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2D:
5218*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().EGLImageOES)
5219*8975f5c5SAndroid Build Coastguard Worker             {
5220*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(type));
5221*8975f5c5SAndroid Build Coastguard Worker             }
5222*8975f5c5SAndroid Build Coastguard Worker             break;
5223*8975f5c5SAndroid Build Coastguard Worker 
5224*8975f5c5SAndroid Build Coastguard Worker         case TextureType::_2DArray:
5225*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().EGLImageArrayEXT)
5226*8975f5c5SAndroid Build Coastguard Worker             {
5227*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(type));
5228*8975f5c5SAndroid Build Coastguard Worker             }
5229*8975f5c5SAndroid Build Coastguard Worker             break;
5230*8975f5c5SAndroid Build Coastguard Worker 
5231*8975f5c5SAndroid Build Coastguard Worker         case TextureType::External:
5232*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().EGLImageExternalOES)
5233*8975f5c5SAndroid Build Coastguard Worker             {
5234*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(type));
5235*8975f5c5SAndroid Build Coastguard Worker             }
5236*8975f5c5SAndroid Build Coastguard Worker             break;
5237*8975f5c5SAndroid Build Coastguard Worker 
5238*8975f5c5SAndroid Build Coastguard Worker         default:
5239*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
5240*8975f5c5SAndroid Build Coastguard Worker             return false;
5241*8975f5c5SAndroid Build Coastguard Worker     }
5242*8975f5c5SAndroid Build Coastguard Worker 
5243*8975f5c5SAndroid Build Coastguard Worker     return ValidateEGLImageObject(context, entryPoint, type, image);
5244*8975f5c5SAndroid Build Coastguard Worker }
5245*8975f5c5SAndroid Build Coastguard Worker 
ValidateEGLImageTargetRenderbufferStorageOES(const Context * context,angle::EntryPoint entryPoint,GLenum target,egl::ImageID image)5246*8975f5c5SAndroid Build Coastguard Worker bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
5247*8975f5c5SAndroid Build Coastguard Worker                                                   angle::EntryPoint entryPoint,
5248*8975f5c5SAndroid Build Coastguard Worker                                                   GLenum target,
5249*8975f5c5SAndroid Build Coastguard Worker                                                   egl::ImageID image)
5250*8975f5c5SAndroid Build Coastguard Worker {
5251*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().EGLImageOES)
5252*8975f5c5SAndroid Build Coastguard Worker     {
5253*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5254*8975f5c5SAndroid Build Coastguard Worker         return false;
5255*8975f5c5SAndroid Build Coastguard Worker     }
5256*8975f5c5SAndroid Build Coastguard Worker 
5257*8975f5c5SAndroid Build Coastguard Worker     switch (target)
5258*8975f5c5SAndroid Build Coastguard Worker     {
5259*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER:
5260*8975f5c5SAndroid Build Coastguard Worker             break;
5261*8975f5c5SAndroid Build Coastguard Worker 
5262*8975f5c5SAndroid Build Coastguard Worker         default:
5263*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
5264*8975f5c5SAndroid Build Coastguard Worker             return false;
5265*8975f5c5SAndroid Build Coastguard Worker     }
5266*8975f5c5SAndroid Build Coastguard Worker 
5267*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context->getDisplay());
5268*8975f5c5SAndroid Build Coastguard Worker     if (!context->getDisplay()->isValidImage(image))
5269*8975f5c5SAndroid Build Coastguard Worker     {
5270*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidEGLImage);
5271*8975f5c5SAndroid Build Coastguard Worker         return false;
5272*8975f5c5SAndroid Build Coastguard Worker     }
5273*8975f5c5SAndroid Build Coastguard Worker 
5274*8975f5c5SAndroid Build Coastguard Worker     egl::Image *imageObject = context->getDisplay()->getImage(image);
5275*8975f5c5SAndroid Build Coastguard Worker     if (!imageObject->isRenderable(context))
5276*8975f5c5SAndroid Build Coastguard Worker     {
5277*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kEGLImageRenderbufferFormatNotSupported);
5278*8975f5c5SAndroid Build Coastguard Worker         return false;
5279*8975f5c5SAndroid Build Coastguard Worker     }
5280*8975f5c5SAndroid Build Coastguard Worker 
5281*8975f5c5SAndroid Build Coastguard Worker     if (imageObject->hasProtectedContent() != context->getState().hasProtectedContent())
5282*8975f5c5SAndroid Build Coastguard Worker     {
5283*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5284*8975f5c5SAndroid Build Coastguard Worker                                "Mismatch between Image and Context Protected Content state");
5285*8975f5c5SAndroid Build Coastguard Worker         return false;
5286*8975f5c5SAndroid Build Coastguard Worker     }
5287*8975f5c5SAndroid Build Coastguard Worker 
5288*8975f5c5SAndroid Build Coastguard Worker     return true;
5289*8975f5c5SAndroid Build Coastguard Worker }
5290*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramBinaryBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum binaryFormat,const void * binary,GLint length)5291*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramBinaryBase(const Context *context,
5292*8975f5c5SAndroid Build Coastguard Worker                                angle::EntryPoint entryPoint,
5293*8975f5c5SAndroid Build Coastguard Worker                                ShaderProgramID program,
5294*8975f5c5SAndroid Build Coastguard Worker                                GLenum binaryFormat,
5295*8975f5c5SAndroid Build Coastguard Worker                                const void *binary,
5296*8975f5c5SAndroid Build Coastguard Worker                                GLint length)
5297*8975f5c5SAndroid Build Coastguard Worker {
5298*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = GetValidProgram(context, entryPoint, program);
5299*8975f5c5SAndroid Build Coastguard Worker     if (programObject == nullptr)
5300*8975f5c5SAndroid Build Coastguard Worker     {
5301*8975f5c5SAndroid Build Coastguard Worker         return false;
5302*8975f5c5SAndroid Build Coastguard Worker     }
5303*8975f5c5SAndroid Build Coastguard Worker 
5304*8975f5c5SAndroid Build Coastguard Worker     const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
5305*8975f5c5SAndroid Build Coastguard Worker     if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
5306*8975f5c5SAndroid Build Coastguard Worker         programBinaryFormats.end())
5307*8975f5c5SAndroid Build Coastguard Worker     {
5308*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramBinaryFormat);
5309*8975f5c5SAndroid Build Coastguard Worker         return false;
5310*8975f5c5SAndroid Build Coastguard Worker     }
5311*8975f5c5SAndroid Build Coastguard Worker 
5312*8975f5c5SAndroid Build Coastguard Worker     if (context->hasActiveTransformFeedback(program))
5313*8975f5c5SAndroid Build Coastguard Worker     {
5314*8975f5c5SAndroid Build Coastguard Worker         // ES 3.0.4 section 2.15 page 91
5315*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackProgramBinary);
5316*8975f5c5SAndroid Build Coastguard Worker         return false;
5317*8975f5c5SAndroid Build Coastguard Worker     }
5318*8975f5c5SAndroid Build Coastguard Worker 
5319*8975f5c5SAndroid Build Coastguard Worker     return true;
5320*8975f5c5SAndroid Build Coastguard Worker }
5321*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetProgramBinaryBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei bufSize,const GLsizei * length,const GLenum * binaryFormat,const void * binary)5322*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProgramBinaryBase(const Context *context,
5323*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
5324*8975f5c5SAndroid Build Coastguard Worker                                   ShaderProgramID program,
5325*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei bufSize,
5326*8975f5c5SAndroid Build Coastguard Worker                                   const GLsizei *length,
5327*8975f5c5SAndroid Build Coastguard Worker                                   const GLenum *binaryFormat,
5328*8975f5c5SAndroid Build Coastguard Worker                                   const void *binary)
5329*8975f5c5SAndroid Build Coastguard Worker {
5330*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = GetValidProgram(context, entryPoint, program);
5331*8975f5c5SAndroid Build Coastguard Worker     if (programObject == nullptr)
5332*8975f5c5SAndroid Build Coastguard Worker     {
5333*8975f5c5SAndroid Build Coastguard Worker         return false;
5334*8975f5c5SAndroid Build Coastguard Worker     }
5335*8975f5c5SAndroid Build Coastguard Worker 
5336*8975f5c5SAndroid Build Coastguard Worker     if (!programObject->isLinked())
5337*8975f5c5SAndroid Build Coastguard Worker     {
5338*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
5339*8975f5c5SAndroid Build Coastguard Worker         return false;
5340*8975f5c5SAndroid Build Coastguard Worker     }
5341*8975f5c5SAndroid Build Coastguard Worker 
5342*8975f5c5SAndroid Build Coastguard Worker     if (context->getCaps().programBinaryFormats.empty())
5343*8975f5c5SAndroid Build Coastguard Worker     {
5344*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoProgramBinaryFormats);
5345*8975f5c5SAndroid Build Coastguard Worker         return false;
5346*8975f5c5SAndroid Build Coastguard Worker     }
5347*8975f5c5SAndroid Build Coastguard Worker 
5348*8975f5c5SAndroid Build Coastguard Worker     return true;
5349*8975f5c5SAndroid Build Coastguard Worker }
5350*8975f5c5SAndroid Build Coastguard Worker 
ValidateDrawBuffersBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum * bufs)5351*8975f5c5SAndroid Build Coastguard Worker bool ValidateDrawBuffersBase(const Context *context,
5352*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
5353*8975f5c5SAndroid Build Coastguard Worker                              GLsizei n,
5354*8975f5c5SAndroid Build Coastguard Worker                              const GLenum *bufs)
5355*8975f5c5SAndroid Build Coastguard Worker {
5356*8975f5c5SAndroid Build Coastguard Worker     // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
5357*8975f5c5SAndroid Build Coastguard Worker     if (n < 0)
5358*8975f5c5SAndroid Build Coastguard Worker     {
5359*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
5360*8975f5c5SAndroid Build Coastguard Worker         return false;
5361*8975f5c5SAndroid Build Coastguard Worker     }
5362*8975f5c5SAndroid Build Coastguard Worker     if (n > context->getCaps().maxDrawBuffers)
5363*8975f5c5SAndroid Build Coastguard Worker     {
5364*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
5365*8975f5c5SAndroid Build Coastguard Worker         return false;
5366*8975f5c5SAndroid Build Coastguard Worker     }
5367*8975f5c5SAndroid Build Coastguard Worker 
5368*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context->getState().getDrawFramebuffer());
5369*8975f5c5SAndroid Build Coastguard Worker     FramebufferID frameBufferId = context->getState().getDrawFramebuffer()->id();
5370*8975f5c5SAndroid Build Coastguard Worker     GLuint maxColorAttachment   = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
5371*8975f5c5SAndroid Build Coastguard Worker 
5372*8975f5c5SAndroid Build Coastguard Worker     // This should come first before the check for the default frame buffer
5373*8975f5c5SAndroid Build Coastguard Worker     // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
5374*8975f5c5SAndroid Build Coastguard Worker     // rather than INVALID_OPERATION
5375*8975f5c5SAndroid Build Coastguard Worker     for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
5376*8975f5c5SAndroid Build Coastguard Worker     {
5377*8975f5c5SAndroid Build Coastguard Worker         const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
5378*8975f5c5SAndroid Build Coastguard Worker 
5379*8975f5c5SAndroid Build Coastguard Worker         if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
5380*8975f5c5SAndroid Build Coastguard Worker             (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
5381*8975f5c5SAndroid Build Coastguard Worker              bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
5382*8975f5c5SAndroid Build Coastguard Worker         {
5383*8975f5c5SAndroid Build Coastguard Worker             // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
5384*8975f5c5SAndroid Build Coastguard Worker             // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
5385*8975f5c5SAndroid Build Coastguard Worker             // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
5386*8975f5c5SAndroid Build Coastguard Worker             // 3.1 is still a bit ambiguous about the error, but future specs are
5387*8975f5c5SAndroid Build Coastguard Worker             // expected to clarify that GL_INVALID_ENUM is the correct error.
5388*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDrawBuffer);
5389*8975f5c5SAndroid Build Coastguard Worker             return false;
5390*8975f5c5SAndroid Build Coastguard Worker         }
5391*8975f5c5SAndroid Build Coastguard Worker         else if (bufs[colorAttachment] >= maxColorAttachment)
5392*8975f5c5SAndroid Build Coastguard Worker         {
5393*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
5394*8975f5c5SAndroid Build Coastguard Worker             return false;
5395*8975f5c5SAndroid Build Coastguard Worker         }
5396*8975f5c5SAndroid Build Coastguard Worker         else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
5397*8975f5c5SAndroid Build Coastguard Worker                  frameBufferId.value != 0)
5398*8975f5c5SAndroid Build Coastguard Worker         {
5399*8975f5c5SAndroid Build Coastguard Worker             // INVALID_OPERATION-GL is bound to buffer and ith argument
5400*8975f5c5SAndroid Build Coastguard Worker             // is not COLOR_ATTACHMENTi or NONE
5401*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawBufferValue);
5402*8975f5c5SAndroid Build Coastguard Worker             return false;
5403*8975f5c5SAndroid Build Coastguard Worker         }
5404*8975f5c5SAndroid Build Coastguard Worker     }
5405*8975f5c5SAndroid Build Coastguard Worker 
5406*8975f5c5SAndroid Build Coastguard Worker     // INVALID_OPERATION is generated if GL is bound to the default framebuffer
5407*8975f5c5SAndroid Build Coastguard Worker     // and n is not 1 or bufs is bound to value other than BACK and NONE
5408*8975f5c5SAndroid Build Coastguard Worker     if (frameBufferId.value == 0)
5409*8975f5c5SAndroid Build Coastguard Worker     {
5410*8975f5c5SAndroid Build Coastguard Worker         if (n != 1)
5411*8975f5c5SAndroid Build Coastguard Worker         {
5412*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawBufferCountForDefault);
5413*8975f5c5SAndroid Build Coastguard Worker             return false;
5414*8975f5c5SAndroid Build Coastguard Worker         }
5415*8975f5c5SAndroid Build Coastguard Worker 
5416*8975f5c5SAndroid Build Coastguard Worker         if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
5417*8975f5c5SAndroid Build Coastguard Worker         {
5418*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferInvalidDrawBuffer);
5419*8975f5c5SAndroid Build Coastguard Worker             return false;
5420*8975f5c5SAndroid Build Coastguard Worker         }
5421*8975f5c5SAndroid Build Coastguard Worker     }
5422*8975f5c5SAndroid Build Coastguard Worker 
5423*8975f5c5SAndroid Build Coastguard Worker     return true;
5424*8975f5c5SAndroid Build Coastguard Worker }
5425*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetBufferPointervBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei * length,void * const * params)5426*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferPointervBase(const Context *context,
5427*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
5428*8975f5c5SAndroid Build Coastguard Worker                                    BufferBinding target,
5429*8975f5c5SAndroid Build Coastguard Worker                                    GLenum pname,
5430*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei *length,
5431*8975f5c5SAndroid Build Coastguard Worker                                    void *const *params)
5432*8975f5c5SAndroid Build Coastguard Worker {
5433*8975f5c5SAndroid Build Coastguard Worker     if (length)
5434*8975f5c5SAndroid Build Coastguard Worker     {
5435*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
5436*8975f5c5SAndroid Build Coastguard Worker     }
5437*8975f5c5SAndroid Build Coastguard Worker 
5438*8975f5c5SAndroid Build Coastguard Worker     if (!context->isValidBufferBinding(target))
5439*8975f5c5SAndroid Build Coastguard Worker     {
5440*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5441*8975f5c5SAndroid Build Coastguard Worker         return false;
5442*8975f5c5SAndroid Build Coastguard Worker     }
5443*8975f5c5SAndroid Build Coastguard Worker 
5444*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
5445*8975f5c5SAndroid Build Coastguard Worker     {
5446*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_MAP_POINTER:
5447*8975f5c5SAndroid Build Coastguard Worker             break;
5448*8975f5c5SAndroid Build Coastguard Worker 
5449*8975f5c5SAndroid Build Coastguard Worker         default:
5450*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5451*8975f5c5SAndroid Build Coastguard Worker             return false;
5452*8975f5c5SAndroid Build Coastguard Worker     }
5453*8975f5c5SAndroid Build Coastguard Worker 
5454*8975f5c5SAndroid Build Coastguard Worker     // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
5455*8975f5c5SAndroid Build Coastguard Worker     // target bound to zero generate an INVALID_OPERATION error."
5456*8975f5c5SAndroid Build Coastguard Worker     // GLES 3.1 section 6.6 explicitly specifies this error.
5457*8975f5c5SAndroid Build Coastguard Worker     if (context->getState().getTargetBuffer(target) == nullptr)
5458*8975f5c5SAndroid Build Coastguard Worker     {
5459*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferPointerNotAvailable);
5460*8975f5c5SAndroid Build Coastguard Worker         return false;
5461*8975f5c5SAndroid Build Coastguard Worker     }
5462*8975f5c5SAndroid Build Coastguard Worker 
5463*8975f5c5SAndroid Build Coastguard Worker     if (length)
5464*8975f5c5SAndroid Build Coastguard Worker     {
5465*8975f5c5SAndroid Build Coastguard Worker         *length = 1;
5466*8975f5c5SAndroid Build Coastguard Worker     }
5467*8975f5c5SAndroid Build Coastguard Worker 
5468*8975f5c5SAndroid Build Coastguard Worker     return true;
5469*8975f5c5SAndroid Build Coastguard Worker }
5470*8975f5c5SAndroid Build Coastguard Worker 
ValidateUnmapBufferBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target)5471*8975f5c5SAndroid Build Coastguard Worker bool ValidateUnmapBufferBase(const Context *context,
5472*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
5473*8975f5c5SAndroid Build Coastguard Worker                              BufferBinding target)
5474*8975f5c5SAndroid Build Coastguard Worker {
5475*8975f5c5SAndroid Build Coastguard Worker     if (!context->isValidBufferBinding(target))
5476*8975f5c5SAndroid Build Coastguard Worker     {
5477*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5478*8975f5c5SAndroid Build Coastguard Worker         return false;
5479*8975f5c5SAndroid Build Coastguard Worker     }
5480*8975f5c5SAndroid Build Coastguard Worker 
5481*8975f5c5SAndroid Build Coastguard Worker     Buffer *buffer = context->getState().getTargetBuffer(target);
5482*8975f5c5SAndroid Build Coastguard Worker 
5483*8975f5c5SAndroid Build Coastguard Worker     if (buffer == nullptr || !buffer->isMapped())
5484*8975f5c5SAndroid Build Coastguard Worker     {
5485*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotMapped);
5486*8975f5c5SAndroid Build Coastguard Worker         return false;
5487*8975f5c5SAndroid Build Coastguard Worker     }
5488*8975f5c5SAndroid Build Coastguard Worker 
5489*8975f5c5SAndroid Build Coastguard Worker     return true;
5490*8975f5c5SAndroid Build Coastguard Worker }
5491*8975f5c5SAndroid Build Coastguard Worker 
ValidateMapBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length,GLbitfield access)5492*8975f5c5SAndroid Build Coastguard Worker bool ValidateMapBufferRangeBase(const Context *context,
5493*8975f5c5SAndroid Build Coastguard Worker                                 angle::EntryPoint entryPoint,
5494*8975f5c5SAndroid Build Coastguard Worker                                 BufferBinding target,
5495*8975f5c5SAndroid Build Coastguard Worker                                 GLintptr offset,
5496*8975f5c5SAndroid Build Coastguard Worker                                 GLsizeiptr length,
5497*8975f5c5SAndroid Build Coastguard Worker                                 GLbitfield access)
5498*8975f5c5SAndroid Build Coastguard Worker {
5499*8975f5c5SAndroid Build Coastguard Worker     if (!context->isValidBufferBinding(target))
5500*8975f5c5SAndroid Build Coastguard Worker     {
5501*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5502*8975f5c5SAndroid Build Coastguard Worker         return false;
5503*8975f5c5SAndroid Build Coastguard Worker     }
5504*8975f5c5SAndroid Build Coastguard Worker 
5505*8975f5c5SAndroid Build Coastguard Worker     if (offset < 0)
5506*8975f5c5SAndroid Build Coastguard Worker     {
5507*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
5508*8975f5c5SAndroid Build Coastguard Worker         return false;
5509*8975f5c5SAndroid Build Coastguard Worker     }
5510*8975f5c5SAndroid Build Coastguard Worker 
5511*8975f5c5SAndroid Build Coastguard Worker     if (length < 0)
5512*8975f5c5SAndroid Build Coastguard Worker     {
5513*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
5514*8975f5c5SAndroid Build Coastguard Worker         return false;
5515*8975f5c5SAndroid Build Coastguard Worker     }
5516*8975f5c5SAndroid Build Coastguard Worker 
5517*8975f5c5SAndroid Build Coastguard Worker     Buffer *buffer = context->getState().getTargetBuffer(target);
5518*8975f5c5SAndroid Build Coastguard Worker 
5519*8975f5c5SAndroid Build Coastguard Worker     if (!buffer)
5520*8975f5c5SAndroid Build Coastguard Worker     {
5521*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotMappable);
5522*8975f5c5SAndroid Build Coastguard Worker         return false;
5523*8975f5c5SAndroid Build Coastguard Worker     }
5524*8975f5c5SAndroid Build Coastguard Worker 
5525*8975f5c5SAndroid Build Coastguard Worker     // Check for buffer overflow
5526*8975f5c5SAndroid Build Coastguard Worker     CheckedNumeric<size_t> checkedOffset(offset);
5527*8975f5c5SAndroid Build Coastguard Worker     auto checkedSize = checkedOffset + length;
5528*8975f5c5SAndroid Build Coastguard Worker 
5529*8975f5c5SAndroid Build Coastguard Worker     if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
5530*8975f5c5SAndroid Build Coastguard Worker     {
5531*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kMapOutOfRange);
5532*8975f5c5SAndroid Build Coastguard Worker         return false;
5533*8975f5c5SAndroid Build Coastguard Worker     }
5534*8975f5c5SAndroid Build Coastguard Worker 
5535*8975f5c5SAndroid Build Coastguard Worker     // Check for invalid bits in the mask
5536*8975f5c5SAndroid Build Coastguard Worker     constexpr GLbitfield kAllAccessBits =
5537*8975f5c5SAndroid Build Coastguard Worker         GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
5538*8975f5c5SAndroid Build Coastguard Worker         GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
5539*8975f5c5SAndroid Build Coastguard Worker 
5540*8975f5c5SAndroid Build Coastguard Worker     if (buffer->isImmutable())
5541*8975f5c5SAndroid Build Coastguard Worker     {
5542*8975f5c5SAndroid Build Coastguard Worker         // GL_EXT_buffer_storage's additions to glMapBufferRange
5543*8975f5c5SAndroid Build Coastguard Worker         constexpr GLbitfield kBufferStorageAccessBits =
5544*8975f5c5SAndroid Build Coastguard Worker             kAllAccessBits | GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT;
5545*8975f5c5SAndroid Build Coastguard Worker 
5546*8975f5c5SAndroid Build Coastguard Worker         if ((access & ~kBufferStorageAccessBits) != 0)
5547*8975f5c5SAndroid Build Coastguard Worker         {
5548*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAccessBits);
5549*8975f5c5SAndroid Build Coastguard Worker             return false;
5550*8975f5c5SAndroid Build Coastguard Worker         }
5551*8975f5c5SAndroid Build Coastguard Worker 
5552*8975f5c5SAndroid Build Coastguard Worker         // It is invalid if any of bufferStorageMatchedAccessBits bits are included in access,
5553*8975f5c5SAndroid Build Coastguard Worker         // but the same bits are not included in the buffer's storage flags
5554*8975f5c5SAndroid Build Coastguard Worker         constexpr GLbitfield kBufferStorageMatchedAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
5555*8975f5c5SAndroid Build Coastguard Worker                                                                GL_MAP_PERSISTENT_BIT_EXT |
5556*8975f5c5SAndroid Build Coastguard Worker                                                                GL_MAP_COHERENT_BIT_EXT;
5557*8975f5c5SAndroid Build Coastguard Worker         GLbitfield accessFlags = access & kBufferStorageMatchedAccessBits;
5558*8975f5c5SAndroid Build Coastguard Worker         if ((accessFlags & buffer->getStorageExtUsageFlags()) != accessFlags)
5559*8975f5c5SAndroid Build Coastguard Worker         {
5560*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBits);
5561*8975f5c5SAndroid Build Coastguard Worker             return false;
5562*8975f5c5SAndroid Build Coastguard Worker         }
5563*8975f5c5SAndroid Build Coastguard Worker     }
5564*8975f5c5SAndroid Build Coastguard Worker     else if ((access & ~kAllAccessBits) != 0)
5565*8975f5c5SAndroid Build Coastguard Worker     {
5566*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAccessBits);
5567*8975f5c5SAndroid Build Coastguard Worker         return false;
5568*8975f5c5SAndroid Build Coastguard Worker     }
5569*8975f5c5SAndroid Build Coastguard Worker 
5570*8975f5c5SAndroid Build Coastguard Worker     if (length == 0)
5571*8975f5c5SAndroid Build Coastguard Worker     {
5572*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kLengthZero);
5573*8975f5c5SAndroid Build Coastguard Worker         return false;
5574*8975f5c5SAndroid Build Coastguard Worker     }
5575*8975f5c5SAndroid Build Coastguard Worker 
5576*8975f5c5SAndroid Build Coastguard Worker     if (buffer->isMapped())
5577*8975f5c5SAndroid Build Coastguard Worker     {
5578*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferAlreadyMapped);
5579*8975f5c5SAndroid Build Coastguard Worker         return false;
5580*8975f5c5SAndroid Build Coastguard Worker     }
5581*8975f5c5SAndroid Build Coastguard Worker 
5582*8975f5c5SAndroid Build Coastguard Worker     // Check for invalid bit combinations
5583*8975f5c5SAndroid Build Coastguard Worker     if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
5584*8975f5c5SAndroid Build Coastguard Worker     {
5585*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite);
5586*8975f5c5SAndroid Build Coastguard Worker         return false;
5587*8975f5c5SAndroid Build Coastguard Worker     }
5588*8975f5c5SAndroid Build Coastguard Worker 
5589*8975f5c5SAndroid Build Coastguard Worker     GLbitfield writeOnlyBits =
5590*8975f5c5SAndroid Build Coastguard Worker         GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
5591*8975f5c5SAndroid Build Coastguard Worker 
5592*8975f5c5SAndroid Build Coastguard Worker     if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
5593*8975f5c5SAndroid Build Coastguard Worker     {
5594*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBitsRead);
5595*8975f5c5SAndroid Build Coastguard Worker         return false;
5596*8975f5c5SAndroid Build Coastguard Worker     }
5597*8975f5c5SAndroid Build Coastguard Worker 
5598*8975f5c5SAndroid Build Coastguard Worker     if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
5599*8975f5c5SAndroid Build Coastguard Worker     {
5600*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAccessBitsFlush);
5601*8975f5c5SAndroid Build Coastguard Worker         return false;
5602*8975f5c5SAndroid Build Coastguard Worker     }
5603*8975f5c5SAndroid Build Coastguard Worker 
5604*8975f5c5SAndroid Build Coastguard Worker     return ValidateMapBufferBase(context, entryPoint, target);
5605*8975f5c5SAndroid Build Coastguard Worker }
5606*8975f5c5SAndroid Build Coastguard Worker 
ValidateFlushMappedBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length)5607*8975f5c5SAndroid Build Coastguard Worker bool ValidateFlushMappedBufferRangeBase(const Context *context,
5608*8975f5c5SAndroid Build Coastguard Worker                                         angle::EntryPoint entryPoint,
5609*8975f5c5SAndroid Build Coastguard Worker                                         BufferBinding target,
5610*8975f5c5SAndroid Build Coastguard Worker                                         GLintptr offset,
5611*8975f5c5SAndroid Build Coastguard Worker                                         GLsizeiptr length)
5612*8975f5c5SAndroid Build Coastguard Worker {
5613*8975f5c5SAndroid Build Coastguard Worker     if (offset < 0)
5614*8975f5c5SAndroid Build Coastguard Worker     {
5615*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
5616*8975f5c5SAndroid Build Coastguard Worker         return false;
5617*8975f5c5SAndroid Build Coastguard Worker     }
5618*8975f5c5SAndroid Build Coastguard Worker 
5619*8975f5c5SAndroid Build Coastguard Worker     if (length < 0)
5620*8975f5c5SAndroid Build Coastguard Worker     {
5621*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
5622*8975f5c5SAndroid Build Coastguard Worker         return false;
5623*8975f5c5SAndroid Build Coastguard Worker     }
5624*8975f5c5SAndroid Build Coastguard Worker 
5625*8975f5c5SAndroid Build Coastguard Worker     if (!context->isValidBufferBinding(target))
5626*8975f5c5SAndroid Build Coastguard Worker     {
5627*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
5628*8975f5c5SAndroid Build Coastguard Worker         return false;
5629*8975f5c5SAndroid Build Coastguard Worker     }
5630*8975f5c5SAndroid Build Coastguard Worker 
5631*8975f5c5SAndroid Build Coastguard Worker     Buffer *buffer = context->getState().getTargetBuffer(target);
5632*8975f5c5SAndroid Build Coastguard Worker 
5633*8975f5c5SAndroid Build Coastguard Worker     if (buffer == nullptr)
5634*8975f5c5SAndroid Build Coastguard Worker     {
5635*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFlushZero);
5636*8975f5c5SAndroid Build Coastguard Worker         return false;
5637*8975f5c5SAndroid Build Coastguard Worker     }
5638*8975f5c5SAndroid Build Coastguard Worker 
5639*8975f5c5SAndroid Build Coastguard Worker     if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
5640*8975f5c5SAndroid Build Coastguard Worker     {
5641*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFlushTarget);
5642*8975f5c5SAndroid Build Coastguard Worker         return false;
5643*8975f5c5SAndroid Build Coastguard Worker     }
5644*8975f5c5SAndroid Build Coastguard Worker 
5645*8975f5c5SAndroid Build Coastguard Worker     // Check for buffer overflow
5646*8975f5c5SAndroid Build Coastguard Worker     CheckedNumeric<size_t> checkedOffset(offset);
5647*8975f5c5SAndroid Build Coastguard Worker     auto checkedSize = checkedOffset + length;
5648*8975f5c5SAndroid Build Coastguard Worker 
5649*8975f5c5SAndroid Build Coastguard Worker     if (!checkedSize.IsValid() ||
5650*8975f5c5SAndroid Build Coastguard Worker         checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
5651*8975f5c5SAndroid Build Coastguard Worker     {
5652*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFlushOutOfRange);
5653*8975f5c5SAndroid Build Coastguard Worker         return false;
5654*8975f5c5SAndroid Build Coastguard Worker     }
5655*8975f5c5SAndroid Build Coastguard Worker 
5656*8975f5c5SAndroid Build Coastguard Worker     return true;
5657*8975f5c5SAndroid Build Coastguard Worker }
5658*8975f5c5SAndroid Build Coastguard Worker 
ValidateGenOrDelete(const Context * context,angle::EntryPoint entryPoint,GLint n)5659*8975f5c5SAndroid Build Coastguard Worker bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n)
5660*8975f5c5SAndroid Build Coastguard Worker {
5661*8975f5c5SAndroid Build Coastguard Worker     if (n < 0)
5662*8975f5c5SAndroid Build Coastguard Worker     {
5663*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
5664*8975f5c5SAndroid Build Coastguard Worker         return false;
5665*8975f5c5SAndroid Build Coastguard Worker     }
5666*8975f5c5SAndroid Build Coastguard Worker     return true;
5667*8975f5c5SAndroid Build Coastguard Worker }
5668*8975f5c5SAndroid Build Coastguard Worker 
ValidateRobustEntryPoint(const Context * context,angle::EntryPoint entryPoint,GLsizei bufSize)5669*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustEntryPoint(const Context *context, angle::EntryPoint entryPoint, GLsizei bufSize)
5670*8975f5c5SAndroid Build Coastguard Worker {
5671*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().robustClientMemoryANGLE)
5672*8975f5c5SAndroid Build Coastguard Worker     {
5673*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5674*8975f5c5SAndroid Build Coastguard Worker         return false;
5675*8975f5c5SAndroid Build Coastguard Worker     }
5676*8975f5c5SAndroid Build Coastguard Worker 
5677*8975f5c5SAndroid Build Coastguard Worker     if (bufSize < 0)
5678*8975f5c5SAndroid Build Coastguard Worker     {
5679*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
5680*8975f5c5SAndroid Build Coastguard Worker         return false;
5681*8975f5c5SAndroid Build Coastguard Worker     }
5682*8975f5c5SAndroid Build Coastguard Worker 
5683*8975f5c5SAndroid Build Coastguard Worker     return true;
5684*8975f5c5SAndroid Build Coastguard Worker }
5685*8975f5c5SAndroid Build Coastguard Worker 
ValidateRobustBufferSize(const Context * context,angle::EntryPoint entryPoint,GLsizei bufSize,GLsizei numParams)5686*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustBufferSize(const Context *context,
5687*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
5688*8975f5c5SAndroid Build Coastguard Worker                               GLsizei bufSize,
5689*8975f5c5SAndroid Build Coastguard Worker                               GLsizei numParams)
5690*8975f5c5SAndroid Build Coastguard Worker {
5691*8975f5c5SAndroid Build Coastguard Worker     if (bufSize < numParams)
5692*8975f5c5SAndroid Build Coastguard Worker     {
5693*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientParams);
5694*8975f5c5SAndroid Build Coastguard Worker         return false;
5695*8975f5c5SAndroid Build Coastguard Worker     }
5696*8975f5c5SAndroid Build Coastguard Worker 
5697*8975f5c5SAndroid Build Coastguard Worker     return true;
5698*8975f5c5SAndroid Build Coastguard Worker }
5699*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetFramebufferAttachmentParameterivBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum pname,GLsizei * numParams)5700*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
5701*8975f5c5SAndroid Build Coastguard Worker                                                      angle::EntryPoint entryPoint,
5702*8975f5c5SAndroid Build Coastguard Worker                                                      GLenum target,
5703*8975f5c5SAndroid Build Coastguard Worker                                                      GLenum attachment,
5704*8975f5c5SAndroid Build Coastguard Worker                                                      GLenum pname,
5705*8975f5c5SAndroid Build Coastguard Worker                                                      GLsizei *numParams)
5706*8975f5c5SAndroid Build Coastguard Worker {
5707*8975f5c5SAndroid Build Coastguard Worker     if (!ValidFramebufferTarget(context, target))
5708*8975f5c5SAndroid Build Coastguard Worker     {
5709*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
5710*8975f5c5SAndroid Build Coastguard Worker         return false;
5711*8975f5c5SAndroid Build Coastguard Worker     }
5712*8975f5c5SAndroid Build Coastguard Worker 
5713*8975f5c5SAndroid Build Coastguard Worker     int clientVersion = context->getClientMajorVersion();
5714*8975f5c5SAndroid Build Coastguard Worker 
5715*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
5716*8975f5c5SAndroid Build Coastguard Worker     {
5717*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
5718*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
5719*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
5720*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
5721*8975f5c5SAndroid Build Coastguard Worker             break;
5722*8975f5c5SAndroid Build Coastguard Worker 
5723*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
5724*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
5725*8975f5c5SAndroid Build Coastguard Worker             if (clientVersion < 3 ||
5726*8975f5c5SAndroid Build Coastguard Worker                 !(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR))
5727*8975f5c5SAndroid Build Coastguard Worker             {
5728*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5729*8975f5c5SAndroid Build Coastguard Worker                 return false;
5730*8975f5c5SAndroid Build Coastguard Worker             }
5731*8975f5c5SAndroid Build Coastguard Worker             break;
5732*8975f5c5SAndroid Build Coastguard Worker 
5733*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
5734*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().multisampledRenderToTextureEXT)
5735*8975f5c5SAndroid Build Coastguard Worker             {
5736*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5737*8975f5c5SAndroid Build Coastguard Worker                 return false;
5738*8975f5c5SAndroid Build Coastguard Worker             }
5739*8975f5c5SAndroid Build Coastguard Worker             break;
5740*8975f5c5SAndroid Build Coastguard Worker 
5741*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
5742*8975f5c5SAndroid Build Coastguard Worker             if (clientVersion < 3 && !context->getExtensions().sRGBEXT)
5743*8975f5c5SAndroid Build Coastguard Worker             {
5744*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5745*8975f5c5SAndroid Build Coastguard Worker                 return false;
5746*8975f5c5SAndroid Build Coastguard Worker             }
5747*8975f5c5SAndroid Build Coastguard Worker             break;
5748*8975f5c5SAndroid Build Coastguard Worker 
5749*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
5750*8975f5c5SAndroid Build Coastguard Worker             if (clientVersion < 3 && !context->getExtensions().colorBufferHalfFloatEXT &&
5751*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().colorBufferFloatRgbCHROMIUM &&
5752*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().colorBufferFloatRgbaCHROMIUM)
5753*8975f5c5SAndroid Build Coastguard Worker             {
5754*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
5755*8975f5c5SAndroid Build Coastguard Worker                 return false;
5756*8975f5c5SAndroid Build Coastguard Worker             }
5757*8975f5c5SAndroid Build Coastguard Worker             break;
5758*8975f5c5SAndroid Build Coastguard Worker 
5759*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
5760*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
5761*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
5762*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
5763*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
5764*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
5765*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
5766*8975f5c5SAndroid Build Coastguard Worker             if (clientVersion < 3)
5767*8975f5c5SAndroid Build Coastguard Worker             {
5768*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES3Required);
5769*8975f5c5SAndroid Build Coastguard Worker                 return false;
5770*8975f5c5SAndroid Build Coastguard Worker             }
5771*8975f5c5SAndroid Build Coastguard Worker             break;
5772*8975f5c5SAndroid Build Coastguard Worker 
5773*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
5774*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().geometryShaderAny() &&
5775*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
5776*8975f5c5SAndroid Build Coastguard Worker             {
5777*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
5778*8975f5c5SAndroid Build Coastguard Worker                 return false;
5779*8975f5c5SAndroid Build Coastguard Worker             }
5780*8975f5c5SAndroid Build Coastguard Worker             break;
5781*8975f5c5SAndroid Build Coastguard Worker 
5782*8975f5c5SAndroid Build Coastguard Worker         default:
5783*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
5784*8975f5c5SAndroid Build Coastguard Worker             return false;
5785*8975f5c5SAndroid Build Coastguard Worker     }
5786*8975f5c5SAndroid Build Coastguard Worker 
5787*8975f5c5SAndroid Build Coastguard Worker     // Determine if the attachment is a valid enum
5788*8975f5c5SAndroid Build Coastguard Worker     switch (attachment)
5789*8975f5c5SAndroid Build Coastguard Worker     {
5790*8975f5c5SAndroid Build Coastguard Worker         case GL_BACK:
5791*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH:
5792*8975f5c5SAndroid Build Coastguard Worker         case GL_STENCIL:
5793*8975f5c5SAndroid Build Coastguard Worker             if (clientVersion < 3)
5794*8975f5c5SAndroid Build Coastguard Worker             {
5795*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5796*8975f5c5SAndroid Build Coastguard Worker                 return false;
5797*8975f5c5SAndroid Build Coastguard Worker             }
5798*8975f5c5SAndroid Build Coastguard Worker             break;
5799*8975f5c5SAndroid Build Coastguard Worker 
5800*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_STENCIL_ATTACHMENT:
5801*8975f5c5SAndroid Build Coastguard Worker             if (clientVersion < 3 && !context->isWebGL1())
5802*8975f5c5SAndroid Build Coastguard Worker             {
5803*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5804*8975f5c5SAndroid Build Coastguard Worker                 return false;
5805*8975f5c5SAndroid Build Coastguard Worker             }
5806*8975f5c5SAndroid Build Coastguard Worker             break;
5807*8975f5c5SAndroid Build Coastguard Worker 
5808*8975f5c5SAndroid Build Coastguard Worker         case GL_COLOR_ATTACHMENT0:
5809*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_ATTACHMENT:
5810*8975f5c5SAndroid Build Coastguard Worker         case GL_STENCIL_ATTACHMENT:
5811*8975f5c5SAndroid Build Coastguard Worker             break;
5812*8975f5c5SAndroid Build Coastguard Worker 
5813*8975f5c5SAndroid Build Coastguard Worker         default:
5814*8975f5c5SAndroid Build Coastguard Worker             if ((clientVersion < 3 && !context->getExtensions().drawBuffersEXT) ||
5815*8975f5c5SAndroid Build Coastguard Worker                 attachment < GL_COLOR_ATTACHMENT0_EXT ||
5816*8975f5c5SAndroid Build Coastguard Worker                 (attachment - GL_COLOR_ATTACHMENT0_EXT) >=
5817*8975f5c5SAndroid Build Coastguard Worker                     static_cast<GLuint>(context->getCaps().maxColorAttachments))
5818*8975f5c5SAndroid Build Coastguard Worker             {
5819*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
5820*8975f5c5SAndroid Build Coastguard Worker                 return false;
5821*8975f5c5SAndroid Build Coastguard Worker             }
5822*8975f5c5SAndroid Build Coastguard Worker             break;
5823*8975f5c5SAndroid Build Coastguard Worker     }
5824*8975f5c5SAndroid Build Coastguard Worker 
5825*8975f5c5SAndroid Build Coastguard Worker     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
5826*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebuffer);
5827*8975f5c5SAndroid Build Coastguard Worker 
5828*8975f5c5SAndroid Build Coastguard Worker     if (framebuffer->isDefault())
5829*8975f5c5SAndroid Build Coastguard Worker     {
5830*8975f5c5SAndroid Build Coastguard Worker         if (clientVersion < 3)
5831*8975f5c5SAndroid Build Coastguard Worker         {
5832*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
5833*8975f5c5SAndroid Build Coastguard Worker             return false;
5834*8975f5c5SAndroid Build Coastguard Worker         }
5835*8975f5c5SAndroid Build Coastguard Worker 
5836*8975f5c5SAndroid Build Coastguard Worker         switch (attachment)
5837*8975f5c5SAndroid Build Coastguard Worker         {
5838*8975f5c5SAndroid Build Coastguard Worker             case GL_BACK:
5839*8975f5c5SAndroid Build Coastguard Worker             case GL_DEPTH:
5840*8975f5c5SAndroid Build Coastguard Worker             case GL_STENCIL:
5841*8975f5c5SAndroid Build Coastguard Worker                 break;
5842*8975f5c5SAndroid Build Coastguard Worker 
5843*8975f5c5SAndroid Build Coastguard Worker             default:
5844*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5845*8975f5c5SAndroid Build Coastguard Worker                 return false;
5846*8975f5c5SAndroid Build Coastguard Worker         }
5847*8975f5c5SAndroid Build Coastguard Worker     }
5848*8975f5c5SAndroid Build Coastguard Worker     else
5849*8975f5c5SAndroid Build Coastguard Worker     {
5850*8975f5c5SAndroid Build Coastguard Worker         if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
5851*8975f5c5SAndroid Build Coastguard Worker         {
5852*8975f5c5SAndroid Build Coastguard Worker             // Valid attachment query
5853*8975f5c5SAndroid Build Coastguard Worker         }
5854*8975f5c5SAndroid Build Coastguard Worker         else
5855*8975f5c5SAndroid Build Coastguard Worker         {
5856*8975f5c5SAndroid Build Coastguard Worker             switch (attachment)
5857*8975f5c5SAndroid Build Coastguard Worker             {
5858*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_ATTACHMENT:
5859*8975f5c5SAndroid Build Coastguard Worker                 case GL_STENCIL_ATTACHMENT:
5860*8975f5c5SAndroid Build Coastguard Worker                     break;
5861*8975f5c5SAndroid Build Coastguard Worker 
5862*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_STENCIL_ATTACHMENT:
5863*8975f5c5SAndroid Build Coastguard Worker                     if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
5864*8975f5c5SAndroid Build Coastguard Worker                     {
5865*8975f5c5SAndroid Build Coastguard Worker                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5866*8975f5c5SAndroid Build Coastguard Worker                         return false;
5867*8975f5c5SAndroid Build Coastguard Worker                     }
5868*8975f5c5SAndroid Build Coastguard Worker                     break;
5869*8975f5c5SAndroid Build Coastguard Worker 
5870*8975f5c5SAndroid Build Coastguard Worker                 default:
5871*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5872*8975f5c5SAndroid Build Coastguard Worker                     return false;
5873*8975f5c5SAndroid Build Coastguard Worker             }
5874*8975f5c5SAndroid Build Coastguard Worker         }
5875*8975f5c5SAndroid Build Coastguard Worker     }
5876*8975f5c5SAndroid Build Coastguard Worker 
5877*8975f5c5SAndroid Build Coastguard Worker     const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
5878*8975f5c5SAndroid Build Coastguard Worker     if (attachmentObject)
5879*8975f5c5SAndroid Build Coastguard Worker     {
5880*8975f5c5SAndroid Build Coastguard Worker         ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
5881*8975f5c5SAndroid Build Coastguard Worker                attachmentObject->type() == GL_TEXTURE ||
5882*8975f5c5SAndroid Build Coastguard Worker                attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
5883*8975f5c5SAndroid Build Coastguard Worker 
5884*8975f5c5SAndroid Build Coastguard Worker         switch (pname)
5885*8975f5c5SAndroid Build Coastguard Worker         {
5886*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
5887*8975f5c5SAndroid Build Coastguard Worker                 if (attachmentObject->type() != GL_RENDERBUFFER &&
5888*8975f5c5SAndroid Build Coastguard Worker                     attachmentObject->type() != GL_TEXTURE)
5889*8975f5c5SAndroid Build Coastguard Worker                 {
5890*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5891*8975f5c5SAndroid Build Coastguard Worker                     return false;
5892*8975f5c5SAndroid Build Coastguard Worker                 }
5893*8975f5c5SAndroid Build Coastguard Worker                 break;
5894*8975f5c5SAndroid Build Coastguard Worker 
5895*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
5896*8975f5c5SAndroid Build Coastguard Worker                 if (attachmentObject->type() != GL_TEXTURE)
5897*8975f5c5SAndroid Build Coastguard Worker                 {
5898*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5899*8975f5c5SAndroid Build Coastguard Worker                     return false;
5900*8975f5c5SAndroid Build Coastguard Worker                 }
5901*8975f5c5SAndroid Build Coastguard Worker                 break;
5902*8975f5c5SAndroid Build Coastguard Worker 
5903*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
5904*8975f5c5SAndroid Build Coastguard Worker                 if (attachmentObject->type() != GL_TEXTURE)
5905*8975f5c5SAndroid Build Coastguard Worker                 {
5906*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5907*8975f5c5SAndroid Build Coastguard Worker                     return false;
5908*8975f5c5SAndroid Build Coastguard Worker                 }
5909*8975f5c5SAndroid Build Coastguard Worker                 break;
5910*8975f5c5SAndroid Build Coastguard Worker 
5911*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
5912*8975f5c5SAndroid Build Coastguard Worker                 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
5913*8975f5c5SAndroid Build Coastguard Worker                 {
5914*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5915*8975f5c5SAndroid Build Coastguard Worker                     return false;
5916*8975f5c5SAndroid Build Coastguard Worker                 }
5917*8975f5c5SAndroid Build Coastguard Worker                 break;
5918*8975f5c5SAndroid Build Coastguard Worker 
5919*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
5920*8975f5c5SAndroid Build Coastguard Worker                 if (attachmentObject->type() != GL_TEXTURE)
5921*8975f5c5SAndroid Build Coastguard Worker                 {
5922*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
5923*8975f5c5SAndroid Build Coastguard Worker                     return false;
5924*8975f5c5SAndroid Build Coastguard Worker                 }
5925*8975f5c5SAndroid Build Coastguard Worker                 break;
5926*8975f5c5SAndroid Build Coastguard Worker 
5927*8975f5c5SAndroid Build Coastguard Worker             default:
5928*8975f5c5SAndroid Build Coastguard Worker                 break;
5929*8975f5c5SAndroid Build Coastguard Worker         }
5930*8975f5c5SAndroid Build Coastguard Worker     }
5931*8975f5c5SAndroid Build Coastguard Worker     else
5932*8975f5c5SAndroid Build Coastguard Worker     {
5933*8975f5c5SAndroid Build Coastguard Worker         // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
5934*8975f5c5SAndroid Build Coastguard Worker         // is NONE, then querying any other pname will generate INVALID_ENUM.
5935*8975f5c5SAndroid Build Coastguard Worker 
5936*8975f5c5SAndroid Build Coastguard Worker         // ES 3.0.2 spec pg 235 states that if the attachment type is none,
5937*8975f5c5SAndroid Build Coastguard Worker         // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
5938*8975f5c5SAndroid Build Coastguard Worker         // INVALID_OPERATION for all other pnames
5939*8975f5c5SAndroid Build Coastguard Worker 
5940*8975f5c5SAndroid Build Coastguard Worker         switch (pname)
5941*8975f5c5SAndroid Build Coastguard Worker         {
5942*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
5943*8975f5c5SAndroid Build Coastguard Worker                 break;
5944*8975f5c5SAndroid Build Coastguard Worker 
5945*8975f5c5SAndroid Build Coastguard Worker             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
5946*8975f5c5SAndroid Build Coastguard Worker                 if (clientVersion < 3)
5947*8975f5c5SAndroid Build Coastguard Worker                 {
5948*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferAttachmentParameter);
5949*8975f5c5SAndroid Build Coastguard Worker                     return false;
5950*8975f5c5SAndroid Build Coastguard Worker                 }
5951*8975f5c5SAndroid Build Coastguard Worker                 break;
5952*8975f5c5SAndroid Build Coastguard Worker 
5953*8975f5c5SAndroid Build Coastguard Worker             default:
5954*8975f5c5SAndroid Build Coastguard Worker                 if (clientVersion < 3)
5955*8975f5c5SAndroid Build Coastguard Worker                 {
5956*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferAttachmentParameter);
5957*8975f5c5SAndroid Build Coastguard Worker                     return false;
5958*8975f5c5SAndroid Build Coastguard Worker                 }
5959*8975f5c5SAndroid Build Coastguard Worker                 else
5960*8975f5c5SAndroid Build Coastguard Worker                 {
5961*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5962*8975f5c5SAndroid Build Coastguard Worker                                            kInvalidFramebufferAttachmentParameter);
5963*8975f5c5SAndroid Build Coastguard Worker                     return false;
5964*8975f5c5SAndroid Build Coastguard Worker                 }
5965*8975f5c5SAndroid Build Coastguard Worker         }
5966*8975f5c5SAndroid Build Coastguard Worker     }
5967*8975f5c5SAndroid Build Coastguard Worker 
5968*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
5969*8975f5c5SAndroid Build Coastguard Worker     {
5970*8975f5c5SAndroid Build Coastguard Worker         *numParams = 1;
5971*8975f5c5SAndroid Build Coastguard Worker     }
5972*8975f5c5SAndroid Build Coastguard Worker 
5973*8975f5c5SAndroid Build Coastguard Worker     return true;
5974*8975f5c5SAndroid Build Coastguard Worker }
5975*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetFramebufferParameterivBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)5976*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFramebufferParameterivBase(const Context *context,
5977*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint entryPoint,
5978*8975f5c5SAndroid Build Coastguard Worker                                            GLenum target,
5979*8975f5c5SAndroid Build Coastguard Worker                                            GLenum pname,
5980*8975f5c5SAndroid Build Coastguard Worker                                            const GLint *params)
5981*8975f5c5SAndroid Build Coastguard Worker {
5982*8975f5c5SAndroid Build Coastguard Worker     if (!ValidFramebufferTarget(context, target))
5983*8975f5c5SAndroid Build Coastguard Worker     {
5984*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
5985*8975f5c5SAndroid Build Coastguard Worker         return false;
5986*8975f5c5SAndroid Build Coastguard Worker     }
5987*8975f5c5SAndroid Build Coastguard Worker 
5988*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
5989*8975f5c5SAndroid Build Coastguard Worker     {
5990*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
5991*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
5992*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
5993*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
5994*8975f5c5SAndroid Build Coastguard Worker             break;
5995*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
5996*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().geometryShaderAny() &&
5997*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
5998*8975f5c5SAndroid Build Coastguard Worker             {
5999*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
6000*8975f5c5SAndroid Build Coastguard Worker                 return false;
6001*8975f5c5SAndroid Build Coastguard Worker             }
6002*8975f5c5SAndroid Build Coastguard Worker             break;
6003*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER_FLIP_Y_MESA:
6004*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().framebufferFlipYMESA)
6005*8975f5c5SAndroid Build Coastguard Worker             {
6006*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
6007*8975f5c5SAndroid Build Coastguard Worker                 return false;
6008*8975f5c5SAndroid Build Coastguard Worker             }
6009*8975f5c5SAndroid Build Coastguard Worker             break;
6010*8975f5c5SAndroid Build Coastguard Worker         default:
6011*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
6012*8975f5c5SAndroid Build Coastguard Worker             return false;
6013*8975f5c5SAndroid Build Coastguard Worker     }
6014*8975f5c5SAndroid Build Coastguard Worker 
6015*8975f5c5SAndroid Build Coastguard Worker     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
6016*8975f5c5SAndroid Build Coastguard Worker     ASSERT(framebuffer);
6017*8975f5c5SAndroid Build Coastguard Worker 
6018*8975f5c5SAndroid Build Coastguard Worker     if (framebuffer->isDefault())
6019*8975f5c5SAndroid Build Coastguard Worker     {
6020*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDefaultFramebuffer);
6021*8975f5c5SAndroid Build Coastguard Worker         return false;
6022*8975f5c5SAndroid Build Coastguard Worker     }
6023*8975f5c5SAndroid Build Coastguard Worker     return true;
6024*8975f5c5SAndroid Build Coastguard Worker }
6025*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6026*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(const Context *context,
6027*8975f5c5SAndroid Build Coastguard Worker                                                             angle::EntryPoint entryPoint,
6028*8975f5c5SAndroid Build Coastguard Worker                                                             GLenum target,
6029*8975f5c5SAndroid Build Coastguard Worker                                                             GLenum attachment,
6030*8975f5c5SAndroid Build Coastguard Worker                                                             GLenum pname,
6031*8975f5c5SAndroid Build Coastguard Worker                                                             GLsizei bufSize,
6032*8975f5c5SAndroid Build Coastguard Worker                                                             const GLsizei *length,
6033*8975f5c5SAndroid Build Coastguard Worker                                                             const GLint *params)
6034*8975f5c5SAndroid Build Coastguard Worker {
6035*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6036*8975f5c5SAndroid Build Coastguard Worker     {
6037*8975f5c5SAndroid Build Coastguard Worker         return false;
6038*8975f5c5SAndroid Build Coastguard Worker     }
6039*8975f5c5SAndroid Build Coastguard Worker 
6040*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6041*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
6042*8975f5c5SAndroid Build Coastguard Worker                                                          pname, &numParams))
6043*8975f5c5SAndroid Build Coastguard Worker     {
6044*8975f5c5SAndroid Build Coastguard Worker         return false;
6045*8975f5c5SAndroid Build Coastguard Worker     }
6046*8975f5c5SAndroid Build Coastguard Worker 
6047*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6048*8975f5c5SAndroid Build Coastguard Worker     {
6049*8975f5c5SAndroid Build Coastguard Worker         return false;
6050*8975f5c5SAndroid Build Coastguard Worker     }
6051*8975f5c5SAndroid Build Coastguard Worker 
6052*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6053*8975f5c5SAndroid Build Coastguard Worker 
6054*8975f5c5SAndroid Build Coastguard Worker     return true;
6055*8975f5c5SAndroid Build Coastguard Worker }
6056*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetBufferParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6057*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferParameterivRobustANGLE(const Context *context,
6058*8975f5c5SAndroid Build Coastguard Worker                                              angle::EntryPoint entryPoint,
6059*8975f5c5SAndroid Build Coastguard Worker                                              BufferBinding target,
6060*8975f5c5SAndroid Build Coastguard Worker                                              GLenum pname,
6061*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei bufSize,
6062*8975f5c5SAndroid Build Coastguard Worker                                              const GLsizei *length,
6063*8975f5c5SAndroid Build Coastguard Worker                                              const GLint *params)
6064*8975f5c5SAndroid Build Coastguard Worker {
6065*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6066*8975f5c5SAndroid Build Coastguard Worker     {
6067*8975f5c5SAndroid Build Coastguard Worker         return false;
6068*8975f5c5SAndroid Build Coastguard Worker     }
6069*8975f5c5SAndroid Build Coastguard Worker 
6070*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6071*8975f5c5SAndroid Build Coastguard Worker 
6072*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams))
6073*8975f5c5SAndroid Build Coastguard Worker     {
6074*8975f5c5SAndroid Build Coastguard Worker         return false;
6075*8975f5c5SAndroid Build Coastguard Worker     }
6076*8975f5c5SAndroid Build Coastguard Worker 
6077*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6078*8975f5c5SAndroid Build Coastguard Worker     {
6079*8975f5c5SAndroid Build Coastguard Worker         return false;
6080*8975f5c5SAndroid Build Coastguard Worker     }
6081*8975f5c5SAndroid Build Coastguard Worker 
6082*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6083*8975f5c5SAndroid Build Coastguard Worker     return true;
6084*8975f5c5SAndroid Build Coastguard Worker }
6085*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetBufferParameteri64vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint64 * params)6086*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferParameteri64vRobustANGLE(const Context *context,
6087*8975f5c5SAndroid Build Coastguard Worker                                                angle::EntryPoint entryPoint,
6088*8975f5c5SAndroid Build Coastguard Worker                                                BufferBinding target,
6089*8975f5c5SAndroid Build Coastguard Worker                                                GLenum pname,
6090*8975f5c5SAndroid Build Coastguard Worker                                                GLsizei bufSize,
6091*8975f5c5SAndroid Build Coastguard Worker                                                const GLsizei *length,
6092*8975f5c5SAndroid Build Coastguard Worker                                                const GLint64 *params)
6093*8975f5c5SAndroid Build Coastguard Worker {
6094*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6095*8975f5c5SAndroid Build Coastguard Worker 
6096*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6097*8975f5c5SAndroid Build Coastguard Worker     {
6098*8975f5c5SAndroid Build Coastguard Worker         return false;
6099*8975f5c5SAndroid Build Coastguard Worker     }
6100*8975f5c5SAndroid Build Coastguard Worker 
6101*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, &numParams))
6102*8975f5c5SAndroid Build Coastguard Worker     {
6103*8975f5c5SAndroid Build Coastguard Worker         return false;
6104*8975f5c5SAndroid Build Coastguard Worker     }
6105*8975f5c5SAndroid Build Coastguard Worker 
6106*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6107*8975f5c5SAndroid Build Coastguard Worker     {
6108*8975f5c5SAndroid Build Coastguard Worker         return false;
6109*8975f5c5SAndroid Build Coastguard Worker     }
6110*8975f5c5SAndroid Build Coastguard Worker 
6111*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6112*8975f5c5SAndroid Build Coastguard Worker 
6113*8975f5c5SAndroid Build Coastguard Worker     return true;
6114*8975f5c5SAndroid Build Coastguard Worker }
6115*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetProgramivBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,GLsizei * numParams)6116*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProgramivBase(const Context *context,
6117*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
6118*8975f5c5SAndroid Build Coastguard Worker                               ShaderProgramID program,
6119*8975f5c5SAndroid Build Coastguard Worker                               GLenum pname,
6120*8975f5c5SAndroid Build Coastguard Worker                               GLsizei *numParams)
6121*8975f5c5SAndroid Build Coastguard Worker {
6122*8975f5c5SAndroid Build Coastguard Worker     // Currently, all GetProgramiv queries return 1 parameter
6123*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
6124*8975f5c5SAndroid Build Coastguard Worker     {
6125*8975f5c5SAndroid Build Coastguard Worker         *numParams = 1;
6126*8975f5c5SAndroid Build Coastguard Worker     }
6127*8975f5c5SAndroid Build Coastguard Worker 
6128*8975f5c5SAndroid Build Coastguard Worker     if (context->isContextLost())
6129*8975f5c5SAndroid Build Coastguard Worker     {
6130*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
6131*8975f5c5SAndroid Build Coastguard Worker 
6132*8975f5c5SAndroid Build Coastguard Worker         if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR)
6133*8975f5c5SAndroid Build Coastguard Worker         {
6134*8975f5c5SAndroid Build Coastguard Worker             // Generate an error but still return true, the context still needs to return a
6135*8975f5c5SAndroid Build Coastguard Worker             // value in this case.
6136*8975f5c5SAndroid Build Coastguard Worker             return true;
6137*8975f5c5SAndroid Build Coastguard Worker         }
6138*8975f5c5SAndroid Build Coastguard Worker         else
6139*8975f5c5SAndroid Build Coastguard Worker         {
6140*8975f5c5SAndroid Build Coastguard Worker             return false;
6141*8975f5c5SAndroid Build Coastguard Worker         }
6142*8975f5c5SAndroid Build Coastguard Worker     }
6143*8975f5c5SAndroid Build Coastguard Worker 
6144*8975f5c5SAndroid Build Coastguard Worker     // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
6145*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
6146*8975f5c5SAndroid Build Coastguard Worker                                  ? GetValidProgramNoResolve(context, entryPoint, program)
6147*8975f5c5SAndroid Build Coastguard Worker                                  : GetValidProgram(context, entryPoint, program);
6148*8975f5c5SAndroid Build Coastguard Worker     if (!programObject)
6149*8975f5c5SAndroid Build Coastguard Worker     {
6150*8975f5c5SAndroid Build Coastguard Worker         return false;
6151*8975f5c5SAndroid Build Coastguard Worker     }
6152*8975f5c5SAndroid Build Coastguard Worker 
6153*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
6154*8975f5c5SAndroid Build Coastguard Worker     {
6155*8975f5c5SAndroid Build Coastguard Worker         case GL_DELETE_STATUS:
6156*8975f5c5SAndroid Build Coastguard Worker         case GL_LINK_STATUS:
6157*8975f5c5SAndroid Build Coastguard Worker         case GL_VALIDATE_STATUS:
6158*8975f5c5SAndroid Build Coastguard Worker         case GL_INFO_LOG_LENGTH:
6159*8975f5c5SAndroid Build Coastguard Worker         case GL_ATTACHED_SHADERS:
6160*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_ATTRIBUTES:
6161*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
6162*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_UNIFORMS:
6163*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_UNIFORM_MAX_LENGTH:
6164*8975f5c5SAndroid Build Coastguard Worker             break;
6165*8975f5c5SAndroid Build Coastguard Worker 
6166*8975f5c5SAndroid Build Coastguard Worker         case GL_PROGRAM_BINARY_READY_ANGLE:
6167*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().programBinaryReadinessQueryANGLE)
6168*8975f5c5SAndroid Build Coastguard Worker             {
6169*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6170*8975f5c5SAndroid Build Coastguard Worker                 return false;
6171*8975f5c5SAndroid Build Coastguard Worker             }
6172*8975f5c5SAndroid Build Coastguard Worker             break;
6173*8975f5c5SAndroid Build Coastguard Worker 
6174*8975f5c5SAndroid Build Coastguard Worker         case GL_PROGRAM_BINARY_LENGTH:
6175*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 &&
6176*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().getProgramBinaryOES)
6177*8975f5c5SAndroid Build Coastguard Worker             {
6178*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6179*8975f5c5SAndroid Build Coastguard Worker                 return false;
6180*8975f5c5SAndroid Build Coastguard Worker             }
6181*8975f5c5SAndroid Build Coastguard Worker             break;
6182*8975f5c5SAndroid Build Coastguard Worker 
6183*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_UNIFORM_BLOCKS:
6184*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
6185*8975f5c5SAndroid Build Coastguard Worker         case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
6186*8975f5c5SAndroid Build Coastguard Worker         case GL_TRANSFORM_FEEDBACK_VARYINGS:
6187*8975f5c5SAndroid Build Coastguard Worker         case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
6188*8975f5c5SAndroid Build Coastguard Worker         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
6189*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3)
6190*8975f5c5SAndroid Build Coastguard Worker             {
6191*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES30);
6192*8975f5c5SAndroid Build Coastguard Worker                 return false;
6193*8975f5c5SAndroid Build Coastguard Worker             }
6194*8975f5c5SAndroid Build Coastguard Worker             break;
6195*8975f5c5SAndroid Build Coastguard Worker 
6196*8975f5c5SAndroid Build Coastguard Worker         case GL_PROGRAM_SEPARABLE:
6197*8975f5c5SAndroid Build Coastguard Worker         case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
6198*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 1))
6199*8975f5c5SAndroid Build Coastguard Worker             {
6200*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
6201*8975f5c5SAndroid Build Coastguard Worker                 return false;
6202*8975f5c5SAndroid Build Coastguard Worker             }
6203*8975f5c5SAndroid Build Coastguard Worker             break;
6204*8975f5c5SAndroid Build Coastguard Worker 
6205*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPUTE_WORK_GROUP_SIZE:
6206*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 1))
6207*8975f5c5SAndroid Build Coastguard Worker             {
6208*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
6209*8975f5c5SAndroid Build Coastguard Worker                 return false;
6210*8975f5c5SAndroid Build Coastguard Worker             }
6211*8975f5c5SAndroid Build Coastguard Worker 
6212*8975f5c5SAndroid Build Coastguard Worker             // [OpenGL ES 3.1] Chapter 7.12 Page 122
6213*8975f5c5SAndroid Build Coastguard Worker             // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
6214*8975f5c5SAndroid Build Coastguard Worker             // program which has not been linked successfully, or which does not contain objects to
6215*8975f5c5SAndroid Build Coastguard Worker             // form a compute shader.
6216*8975f5c5SAndroid Build Coastguard Worker             if (!programObject->isLinked())
6217*8975f5c5SAndroid Build Coastguard Worker             {
6218*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6219*8975f5c5SAndroid Build Coastguard Worker                 return false;
6220*8975f5c5SAndroid Build Coastguard Worker             }
6221*8975f5c5SAndroid Build Coastguard Worker             if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Compute))
6222*8975f5c5SAndroid Build Coastguard Worker             {
6223*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
6224*8975f5c5SAndroid Build Coastguard Worker                 return false;
6225*8975f5c5SAndroid Build Coastguard Worker             }
6226*8975f5c5SAndroid Build Coastguard Worker             break;
6227*8975f5c5SAndroid Build Coastguard Worker 
6228*8975f5c5SAndroid Build Coastguard Worker         case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
6229*8975f5c5SAndroid Build Coastguard Worker         case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
6230*8975f5c5SAndroid Build Coastguard Worker         case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
6231*8975f5c5SAndroid Build Coastguard Worker         case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
6232*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().geometryShaderAny() &&
6233*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
6234*8975f5c5SAndroid Build Coastguard Worker             {
6235*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
6236*8975f5c5SAndroid Build Coastguard Worker                 return false;
6237*8975f5c5SAndroid Build Coastguard Worker             }
6238*8975f5c5SAndroid Build Coastguard Worker 
6239*8975f5c5SAndroid Build Coastguard Worker             // [EXT_geometry_shader] Chapter 7.12
6240*8975f5c5SAndroid Build Coastguard Worker             // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
6241*8975f5c5SAndroid Build Coastguard Worker             // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
6242*8975f5c5SAndroid Build Coastguard Worker             // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
6243*8975f5c5SAndroid Build Coastguard Worker             // successfully, or which does not contain objects to form a geometry shader.
6244*8975f5c5SAndroid Build Coastguard Worker             if (!programObject->isLinked())
6245*8975f5c5SAndroid Build Coastguard Worker             {
6246*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6247*8975f5c5SAndroid Build Coastguard Worker                 return false;
6248*8975f5c5SAndroid Build Coastguard Worker             }
6249*8975f5c5SAndroid Build Coastguard Worker             if (!programObject->getExecutable().hasLinkedShaderStage(ShaderType::Geometry))
6250*8975f5c5SAndroid Build Coastguard Worker             {
6251*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
6252*8975f5c5SAndroid Build Coastguard Worker                 return false;
6253*8975f5c5SAndroid Build Coastguard Worker             }
6254*8975f5c5SAndroid Build Coastguard Worker             break;
6255*8975f5c5SAndroid Build Coastguard Worker 
6256*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPLETION_STATUS_KHR:
6257*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().parallelShaderCompileKHR)
6258*8975f5c5SAndroid Build Coastguard Worker             {
6259*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6260*8975f5c5SAndroid Build Coastguard Worker                 return false;
6261*8975f5c5SAndroid Build Coastguard Worker             }
6262*8975f5c5SAndroid Build Coastguard Worker             break;
6263*8975f5c5SAndroid Build Coastguard Worker         case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
6264*8975f5c5SAndroid Build Coastguard Worker         case GL_TESS_GEN_MODE_EXT:
6265*8975f5c5SAndroid Build Coastguard Worker         case GL_TESS_GEN_SPACING_EXT:
6266*8975f5c5SAndroid Build Coastguard Worker         case GL_TESS_GEN_VERTEX_ORDER_EXT:
6267*8975f5c5SAndroid Build Coastguard Worker         case GL_TESS_GEN_POINT_MODE_EXT:
6268*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().tessellationShaderAny() &&
6269*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
6270*8975f5c5SAndroid Build Coastguard Worker             {
6271*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTessellationShaderEXTNotEnabled);
6272*8975f5c5SAndroid Build Coastguard Worker                 return false;
6273*8975f5c5SAndroid Build Coastguard Worker             }
6274*8975f5c5SAndroid Build Coastguard Worker             if (!programObject->isLinked())
6275*8975f5c5SAndroid Build Coastguard Worker             {
6276*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6277*8975f5c5SAndroid Build Coastguard Worker                 return false;
6278*8975f5c5SAndroid Build Coastguard Worker             }
6279*8975f5c5SAndroid Build Coastguard Worker             break;
6280*8975f5c5SAndroid Build Coastguard Worker         default:
6281*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6282*8975f5c5SAndroid Build Coastguard Worker             return false;
6283*8975f5c5SAndroid Build Coastguard Worker     }
6284*8975f5c5SAndroid Build Coastguard Worker 
6285*8975f5c5SAndroid Build Coastguard Worker     return true;
6286*8975f5c5SAndroid Build Coastguard Worker }
6287*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetProgramivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6288*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetProgramivRobustANGLE(const Context *context,
6289*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
6290*8975f5c5SAndroid Build Coastguard Worker                                      ShaderProgramID program,
6291*8975f5c5SAndroid Build Coastguard Worker                                      GLenum pname,
6292*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei bufSize,
6293*8975f5c5SAndroid Build Coastguard Worker                                      const GLsizei *length,
6294*8975f5c5SAndroid Build Coastguard Worker                                      const GLint *params)
6295*8975f5c5SAndroid Build Coastguard Worker {
6296*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6297*8975f5c5SAndroid Build Coastguard Worker     {
6298*8975f5c5SAndroid Build Coastguard Worker         return false;
6299*8975f5c5SAndroid Build Coastguard Worker     }
6300*8975f5c5SAndroid Build Coastguard Worker 
6301*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6302*8975f5c5SAndroid Build Coastguard Worker 
6303*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetProgramivBase(context, entryPoint, program, pname, &numParams))
6304*8975f5c5SAndroid Build Coastguard Worker     {
6305*8975f5c5SAndroid Build Coastguard Worker         return false;
6306*8975f5c5SAndroid Build Coastguard Worker     }
6307*8975f5c5SAndroid Build Coastguard Worker 
6308*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6309*8975f5c5SAndroid Build Coastguard Worker     {
6310*8975f5c5SAndroid Build Coastguard Worker         return false;
6311*8975f5c5SAndroid Build Coastguard Worker     }
6312*8975f5c5SAndroid Build Coastguard Worker 
6313*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6314*8975f5c5SAndroid Build Coastguard Worker 
6315*8975f5c5SAndroid Build Coastguard Worker     return true;
6316*8975f5c5SAndroid Build Coastguard Worker }
6317*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetRenderbufferParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6318*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetRenderbufferParameterivRobustANGLE(const Context *context,
6319*8975f5c5SAndroid Build Coastguard Worker                                                    angle::EntryPoint entryPoint,
6320*8975f5c5SAndroid Build Coastguard Worker                                                    GLenum target,
6321*8975f5c5SAndroid Build Coastguard Worker                                                    GLenum pname,
6322*8975f5c5SAndroid Build Coastguard Worker                                                    GLsizei bufSize,
6323*8975f5c5SAndroid Build Coastguard Worker                                                    const GLsizei *length,
6324*8975f5c5SAndroid Build Coastguard Worker                                                    const GLint *params)
6325*8975f5c5SAndroid Build Coastguard Worker {
6326*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6327*8975f5c5SAndroid Build Coastguard Worker     {
6328*8975f5c5SAndroid Build Coastguard Worker         return false;
6329*8975f5c5SAndroid Build Coastguard Worker     }
6330*8975f5c5SAndroid Build Coastguard Worker 
6331*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6332*8975f5c5SAndroid Build Coastguard Worker 
6333*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, &numParams))
6334*8975f5c5SAndroid Build Coastguard Worker     {
6335*8975f5c5SAndroid Build Coastguard Worker         return false;
6336*8975f5c5SAndroid Build Coastguard Worker     }
6337*8975f5c5SAndroid Build Coastguard Worker 
6338*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6339*8975f5c5SAndroid Build Coastguard Worker     {
6340*8975f5c5SAndroid Build Coastguard Worker         return false;
6341*8975f5c5SAndroid Build Coastguard Worker     }
6342*8975f5c5SAndroid Build Coastguard Worker 
6343*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6344*8975f5c5SAndroid Build Coastguard Worker 
6345*8975f5c5SAndroid Build Coastguard Worker     return true;
6346*8975f5c5SAndroid Build Coastguard Worker }
6347*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetShaderivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6348*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetShaderivRobustANGLE(const Context *context,
6349*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
6350*8975f5c5SAndroid Build Coastguard Worker                                     ShaderProgramID shader,
6351*8975f5c5SAndroid Build Coastguard Worker                                     GLenum pname,
6352*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei bufSize,
6353*8975f5c5SAndroid Build Coastguard Worker                                     const GLsizei *length,
6354*8975f5c5SAndroid Build Coastguard Worker                                     const GLint *params)
6355*8975f5c5SAndroid Build Coastguard Worker {
6356*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6357*8975f5c5SAndroid Build Coastguard Worker     {
6358*8975f5c5SAndroid Build Coastguard Worker         return false;
6359*8975f5c5SAndroid Build Coastguard Worker     }
6360*8975f5c5SAndroid Build Coastguard Worker 
6361*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6362*8975f5c5SAndroid Build Coastguard Worker 
6363*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetShaderivBase(context, entryPoint, shader, pname, &numParams))
6364*8975f5c5SAndroid Build Coastguard Worker     {
6365*8975f5c5SAndroid Build Coastguard Worker         return false;
6366*8975f5c5SAndroid Build Coastguard Worker     }
6367*8975f5c5SAndroid Build Coastguard Worker 
6368*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6369*8975f5c5SAndroid Build Coastguard Worker     {
6370*8975f5c5SAndroid Build Coastguard Worker         return false;
6371*8975f5c5SAndroid Build Coastguard Worker     }
6372*8975f5c5SAndroid Build Coastguard Worker 
6373*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6374*8975f5c5SAndroid Build Coastguard Worker 
6375*8975f5c5SAndroid Build Coastguard Worker     return true;
6376*8975f5c5SAndroid Build Coastguard Worker }
6377*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetTexParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)6378*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterfvRobustANGLE(const Context *context,
6379*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
6380*8975f5c5SAndroid Build Coastguard Worker                                           TextureType target,
6381*8975f5c5SAndroid Build Coastguard Worker                                           GLenum pname,
6382*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei bufSize,
6383*8975f5c5SAndroid Build Coastguard Worker                                           const GLsizei *length,
6384*8975f5c5SAndroid Build Coastguard Worker                                           const GLfloat *params)
6385*8975f5c5SAndroid Build Coastguard Worker {
6386*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6387*8975f5c5SAndroid Build Coastguard Worker     {
6388*8975f5c5SAndroid Build Coastguard Worker         return false;
6389*8975f5c5SAndroid Build Coastguard Worker     }
6390*8975f5c5SAndroid Build Coastguard Worker 
6391*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6392*8975f5c5SAndroid Build Coastguard Worker 
6393*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams))
6394*8975f5c5SAndroid Build Coastguard Worker     {
6395*8975f5c5SAndroid Build Coastguard Worker         return false;
6396*8975f5c5SAndroid Build Coastguard Worker     }
6397*8975f5c5SAndroid Build Coastguard Worker 
6398*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6399*8975f5c5SAndroid Build Coastguard Worker     {
6400*8975f5c5SAndroid Build Coastguard Worker         return false;
6401*8975f5c5SAndroid Build Coastguard Worker     }
6402*8975f5c5SAndroid Build Coastguard Worker 
6403*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6404*8975f5c5SAndroid Build Coastguard Worker 
6405*8975f5c5SAndroid Build Coastguard Worker     return true;
6406*8975f5c5SAndroid Build Coastguard Worker }
6407*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetTexParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6408*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterivRobustANGLE(const Context *context,
6409*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
6410*8975f5c5SAndroid Build Coastguard Worker                                           TextureType target,
6411*8975f5c5SAndroid Build Coastguard Worker                                           GLenum pname,
6412*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei bufSize,
6413*8975f5c5SAndroid Build Coastguard Worker                                           const GLsizei *length,
6414*8975f5c5SAndroid Build Coastguard Worker                                           const GLint *params)
6415*8975f5c5SAndroid Build Coastguard Worker {
6416*8975f5c5SAndroid Build Coastguard Worker 
6417*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6418*8975f5c5SAndroid Build Coastguard Worker     {
6419*8975f5c5SAndroid Build Coastguard Worker         return false;
6420*8975f5c5SAndroid Build Coastguard Worker     }
6421*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6422*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetTexParameterBase(context, entryPoint, target, pname, &numParams))
6423*8975f5c5SAndroid Build Coastguard Worker     {
6424*8975f5c5SAndroid Build Coastguard Worker         return false;
6425*8975f5c5SAndroid Build Coastguard Worker     }
6426*8975f5c5SAndroid Build Coastguard Worker 
6427*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6428*8975f5c5SAndroid Build Coastguard Worker     {
6429*8975f5c5SAndroid Build Coastguard Worker         return false;
6430*8975f5c5SAndroid Build Coastguard Worker     }
6431*8975f5c5SAndroid Build Coastguard Worker 
6432*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6433*8975f5c5SAndroid Build Coastguard Worker     return true;
6434*8975f5c5SAndroid Build Coastguard Worker }
6435*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetTexParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6436*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterIivRobustANGLE(const Context *context,
6437*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint entryPoint,
6438*8975f5c5SAndroid Build Coastguard Worker                                            TextureType target,
6439*8975f5c5SAndroid Build Coastguard Worker                                            GLenum pname,
6440*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei bufSize,
6441*8975f5c5SAndroid Build Coastguard Worker                                            const GLsizei *length,
6442*8975f5c5SAndroid Build Coastguard Worker                                            const GLint *params)
6443*8975f5c5SAndroid Build Coastguard Worker {
6444*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6445*8975f5c5SAndroid Build Coastguard Worker     return false;
6446*8975f5c5SAndroid Build Coastguard Worker }
6447*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetTexParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)6448*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterIuivRobustANGLE(const Context *context,
6449*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
6450*8975f5c5SAndroid Build Coastguard Worker                                             TextureType target,
6451*8975f5c5SAndroid Build Coastguard Worker                                             GLenum pname,
6452*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei bufSize,
6453*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei *length,
6454*8975f5c5SAndroid Build Coastguard Worker                                             const GLuint *params)
6455*8975f5c5SAndroid Build Coastguard Worker {
6456*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6457*8975f5c5SAndroid Build Coastguard Worker     return false;
6458*8975f5c5SAndroid Build Coastguard Worker }
6459*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLfloat * params)6460*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterfvRobustANGLE(const Context *context,
6461*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
6462*8975f5c5SAndroid Build Coastguard Worker                                        TextureType target,
6463*8975f5c5SAndroid Build Coastguard Worker                                        GLenum pname,
6464*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei bufSize,
6465*8975f5c5SAndroid Build Coastguard Worker                                        const GLfloat *params)
6466*8975f5c5SAndroid Build Coastguard Worker {
6467*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6468*8975f5c5SAndroid Build Coastguard Worker     {
6469*8975f5c5SAndroid Build Coastguard Worker         return false;
6470*8975f5c5SAndroid Build Coastguard Worker     }
6471*8975f5c5SAndroid Build Coastguard Worker 
6472*8975f5c5SAndroid Build Coastguard Worker     return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params);
6473*8975f5c5SAndroid Build Coastguard Worker }
6474*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)6475*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterivRobustANGLE(const Context *context,
6476*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint entryPoint,
6477*8975f5c5SAndroid Build Coastguard Worker                                        TextureType target,
6478*8975f5c5SAndroid Build Coastguard Worker                                        GLenum pname,
6479*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei bufSize,
6480*8975f5c5SAndroid Build Coastguard Worker                                        const GLint *params)
6481*8975f5c5SAndroid Build Coastguard Worker {
6482*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6483*8975f5c5SAndroid Build Coastguard Worker     {
6484*8975f5c5SAndroid Build Coastguard Worker         return false;
6485*8975f5c5SAndroid Build Coastguard Worker     }
6486*8975f5c5SAndroid Build Coastguard Worker 
6487*8975f5c5SAndroid Build Coastguard Worker     return ValidateTexParameterBase(context, entryPoint, target, pname, bufSize, true, params);
6488*8975f5c5SAndroid Build Coastguard Worker }
6489*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLint * params)6490*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterIivRobustANGLE(const Context *context,
6491*8975f5c5SAndroid Build Coastguard Worker                                         angle::EntryPoint entryPoint,
6492*8975f5c5SAndroid Build Coastguard Worker                                         TextureType target,
6493*8975f5c5SAndroid Build Coastguard Worker                                         GLenum pname,
6494*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei bufSize,
6495*8975f5c5SAndroid Build Coastguard Worker                                         const GLint *params)
6496*8975f5c5SAndroid Build Coastguard Worker {
6497*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6498*8975f5c5SAndroid Build Coastguard Worker     return false;
6499*8975f5c5SAndroid Build Coastguard Worker }
6500*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,const GLuint * params)6501*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterIuivRobustANGLE(const Context *context,
6502*8975f5c5SAndroid Build Coastguard Worker                                          angle::EntryPoint entryPoint,
6503*8975f5c5SAndroid Build Coastguard Worker                                          TextureType target,
6504*8975f5c5SAndroid Build Coastguard Worker                                          GLenum pname,
6505*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei bufSize,
6506*8975f5c5SAndroid Build Coastguard Worker                                          const GLuint *params)
6507*8975f5c5SAndroid Build Coastguard Worker {
6508*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6509*8975f5c5SAndroid Build Coastguard Worker     return false;
6510*8975f5c5SAndroid Build Coastguard Worker }
6511*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSamplerParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)6512*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterfvRobustANGLE(const Context *context,
6513*8975f5c5SAndroid Build Coastguard Worker                                               angle::EntryPoint entryPoint,
6514*8975f5c5SAndroid Build Coastguard Worker                                               SamplerID sampler,
6515*8975f5c5SAndroid Build Coastguard Worker                                               GLenum pname,
6516*8975f5c5SAndroid Build Coastguard Worker                                               GLsizei bufSize,
6517*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei *length,
6518*8975f5c5SAndroid Build Coastguard Worker                                               const GLfloat *params)
6519*8975f5c5SAndroid Build Coastguard Worker {
6520*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6521*8975f5c5SAndroid Build Coastguard Worker     {
6522*8975f5c5SAndroid Build Coastguard Worker         return false;
6523*8975f5c5SAndroid Build Coastguard Worker     }
6524*8975f5c5SAndroid Build Coastguard Worker 
6525*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6526*8975f5c5SAndroid Build Coastguard Worker 
6527*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams))
6528*8975f5c5SAndroid Build Coastguard Worker     {
6529*8975f5c5SAndroid Build Coastguard Worker         return false;
6530*8975f5c5SAndroid Build Coastguard Worker     }
6531*8975f5c5SAndroid Build Coastguard Worker 
6532*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6533*8975f5c5SAndroid Build Coastguard Worker     {
6534*8975f5c5SAndroid Build Coastguard Worker         return false;
6535*8975f5c5SAndroid Build Coastguard Worker     }
6536*8975f5c5SAndroid Build Coastguard Worker 
6537*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6538*8975f5c5SAndroid Build Coastguard Worker     return true;
6539*8975f5c5SAndroid Build Coastguard Worker }
6540*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSamplerParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6541*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterivRobustANGLE(const Context *context,
6542*8975f5c5SAndroid Build Coastguard Worker                                               angle::EntryPoint entryPoint,
6543*8975f5c5SAndroid Build Coastguard Worker                                               SamplerID sampler,
6544*8975f5c5SAndroid Build Coastguard Worker                                               GLenum pname,
6545*8975f5c5SAndroid Build Coastguard Worker                                               GLsizei bufSize,
6546*8975f5c5SAndroid Build Coastguard Worker                                               const GLsizei *length,
6547*8975f5c5SAndroid Build Coastguard Worker                                               const GLint *params)
6548*8975f5c5SAndroid Build Coastguard Worker {
6549*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6550*8975f5c5SAndroid Build Coastguard Worker     {
6551*8975f5c5SAndroid Build Coastguard Worker         return false;
6552*8975f5c5SAndroid Build Coastguard Worker     }
6553*8975f5c5SAndroid Build Coastguard Worker 
6554*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6555*8975f5c5SAndroid Build Coastguard Worker 
6556*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, &numParams))
6557*8975f5c5SAndroid Build Coastguard Worker     {
6558*8975f5c5SAndroid Build Coastguard Worker         return false;
6559*8975f5c5SAndroid Build Coastguard Worker     }
6560*8975f5c5SAndroid Build Coastguard Worker 
6561*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6562*8975f5c5SAndroid Build Coastguard Worker     {
6563*8975f5c5SAndroid Build Coastguard Worker         return false;
6564*8975f5c5SAndroid Build Coastguard Worker     }
6565*8975f5c5SAndroid Build Coastguard Worker 
6566*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6567*8975f5c5SAndroid Build Coastguard Worker     return true;
6568*8975f5c5SAndroid Build Coastguard Worker }
6569*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSamplerParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6570*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterIivRobustANGLE(const Context *context,
6571*8975f5c5SAndroid Build Coastguard Worker                                                angle::EntryPoint entryPoint,
6572*8975f5c5SAndroid Build Coastguard Worker                                                SamplerID sampler,
6573*8975f5c5SAndroid Build Coastguard Worker                                                GLenum pname,
6574*8975f5c5SAndroid Build Coastguard Worker                                                GLsizei bufSize,
6575*8975f5c5SAndroid Build Coastguard Worker                                                const GLsizei *length,
6576*8975f5c5SAndroid Build Coastguard Worker                                                const GLint *params)
6577*8975f5c5SAndroid Build Coastguard Worker {
6578*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6579*8975f5c5SAndroid Build Coastguard Worker     return false;
6580*8975f5c5SAndroid Build Coastguard Worker }
6581*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSamplerParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)6582*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterIuivRobustANGLE(const Context *context,
6583*8975f5c5SAndroid Build Coastguard Worker                                                 angle::EntryPoint entryPoint,
6584*8975f5c5SAndroid Build Coastguard Worker                                                 SamplerID sampler,
6585*8975f5c5SAndroid Build Coastguard Worker                                                 GLenum pname,
6586*8975f5c5SAndroid Build Coastguard Worker                                                 GLsizei bufSize,
6587*8975f5c5SAndroid Build Coastguard Worker                                                 const GLsizei *length,
6588*8975f5c5SAndroid Build Coastguard Worker                                                 const GLuint *params)
6589*8975f5c5SAndroid Build Coastguard Worker {
6590*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6591*8975f5c5SAndroid Build Coastguard Worker     return false;
6592*8975f5c5SAndroid Build Coastguard Worker }
6593*8975f5c5SAndroid Build Coastguard Worker 
ValidateSamplerParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLfloat * params)6594*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterfvRobustANGLE(const Context *context,
6595*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint entryPoint,
6596*8975f5c5SAndroid Build Coastguard Worker                                            SamplerID sampler,
6597*8975f5c5SAndroid Build Coastguard Worker                                            GLenum pname,
6598*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei bufSize,
6599*8975f5c5SAndroid Build Coastguard Worker                                            const GLfloat *params)
6600*8975f5c5SAndroid Build Coastguard Worker {
6601*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6602*8975f5c5SAndroid Build Coastguard Worker     {
6603*8975f5c5SAndroid Build Coastguard Worker         return false;
6604*8975f5c5SAndroid Build Coastguard Worker     }
6605*8975f5c5SAndroid Build Coastguard Worker 
6606*8975f5c5SAndroid Build Coastguard Worker     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params);
6607*8975f5c5SAndroid Build Coastguard Worker }
6608*8975f5c5SAndroid Build Coastguard Worker 
ValidateSamplerParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * params)6609*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterivRobustANGLE(const Context *context,
6610*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint entryPoint,
6611*8975f5c5SAndroid Build Coastguard Worker                                            SamplerID sampler,
6612*8975f5c5SAndroid Build Coastguard Worker                                            GLenum pname,
6613*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei bufSize,
6614*8975f5c5SAndroid Build Coastguard Worker                                            const GLint *params)
6615*8975f5c5SAndroid Build Coastguard Worker {
6616*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6617*8975f5c5SAndroid Build Coastguard Worker     {
6618*8975f5c5SAndroid Build Coastguard Worker         return false;
6619*8975f5c5SAndroid Build Coastguard Worker     }
6620*8975f5c5SAndroid Build Coastguard Worker 
6621*8975f5c5SAndroid Build Coastguard Worker     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, bufSize, true, params);
6622*8975f5c5SAndroid Build Coastguard Worker }
6623*8975f5c5SAndroid Build Coastguard Worker 
ValidateSamplerParameterIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLint * param)6624*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterIivRobustANGLE(const Context *context,
6625*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
6626*8975f5c5SAndroid Build Coastguard Worker                                             SamplerID sampler,
6627*8975f5c5SAndroid Build Coastguard Worker                                             GLenum pname,
6628*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei bufSize,
6629*8975f5c5SAndroid Build Coastguard Worker                                             const GLint *param)
6630*8975f5c5SAndroid Build Coastguard Worker {
6631*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6632*8975f5c5SAndroid Build Coastguard Worker     return false;
6633*8975f5c5SAndroid Build Coastguard Worker }
6634*8975f5c5SAndroid Build Coastguard Worker 
ValidateSamplerParameterIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,const GLuint * param)6635*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterIuivRobustANGLE(const Context *context,
6636*8975f5c5SAndroid Build Coastguard Worker                                              angle::EntryPoint entryPoint,
6637*8975f5c5SAndroid Build Coastguard Worker                                              SamplerID sampler,
6638*8975f5c5SAndroid Build Coastguard Worker                                              GLenum pname,
6639*8975f5c5SAndroid Build Coastguard Worker                                              GLsizei bufSize,
6640*8975f5c5SAndroid Build Coastguard Worker                                              const GLuint *param)
6641*8975f5c5SAndroid Build Coastguard Worker {
6642*8975f5c5SAndroid Build Coastguard Worker     UNIMPLEMENTED();
6643*8975f5c5SAndroid Build Coastguard Worker     return false;
6644*8975f5c5SAndroid Build Coastguard Worker }
6645*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetVertexAttribfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)6646*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribfvRobustANGLE(const Context *context,
6647*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
6648*8975f5c5SAndroid Build Coastguard Worker                                           GLuint index,
6649*8975f5c5SAndroid Build Coastguard Worker                                           GLenum pname,
6650*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei bufSize,
6651*8975f5c5SAndroid Build Coastguard Worker                                           const GLsizei *length,
6652*8975f5c5SAndroid Build Coastguard Worker                                           const GLfloat *params)
6653*8975f5c5SAndroid Build Coastguard Worker {
6654*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6655*8975f5c5SAndroid Build Coastguard Worker     {
6656*8975f5c5SAndroid Build Coastguard Worker         return false;
6657*8975f5c5SAndroid Build Coastguard Worker     }
6658*8975f5c5SAndroid Build Coastguard Worker 
6659*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
6660*8975f5c5SAndroid Build Coastguard Worker 
6661*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false))
6662*8975f5c5SAndroid Build Coastguard Worker     {
6663*8975f5c5SAndroid Build Coastguard Worker         return false;
6664*8975f5c5SAndroid Build Coastguard Worker     }
6665*8975f5c5SAndroid Build Coastguard Worker 
6666*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6667*8975f5c5SAndroid Build Coastguard Worker     {
6668*8975f5c5SAndroid Build Coastguard Worker         return false;
6669*8975f5c5SAndroid Build Coastguard Worker     }
6670*8975f5c5SAndroid Build Coastguard Worker 
6671*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
6672*8975f5c5SAndroid Build Coastguard Worker     return true;
6673*8975f5c5SAndroid Build Coastguard Worker }
6674*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetVertexAttribivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6675*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribivRobustANGLE(const Context *context,
6676*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
6677*8975f5c5SAndroid Build Coastguard Worker                                           GLuint index,
6678*8975f5c5SAndroid Build Coastguard Worker                                           GLenum pname,
6679*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei bufSize,
6680*8975f5c5SAndroid Build Coastguard Worker                                           const GLsizei *length,
6681*8975f5c5SAndroid Build Coastguard Worker                                           const GLint *params)
6682*8975f5c5SAndroid Build Coastguard Worker {
6683*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6684*8975f5c5SAndroid Build Coastguard Worker     {
6685*8975f5c5SAndroid Build Coastguard Worker         return false;
6686*8975f5c5SAndroid Build Coastguard Worker     }
6687*8975f5c5SAndroid Build Coastguard Worker 
6688*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
6689*8975f5c5SAndroid Build Coastguard Worker 
6690*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, false))
6691*8975f5c5SAndroid Build Coastguard Worker     {
6692*8975f5c5SAndroid Build Coastguard Worker         return false;
6693*8975f5c5SAndroid Build Coastguard Worker     }
6694*8975f5c5SAndroid Build Coastguard Worker 
6695*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6696*8975f5c5SAndroid Build Coastguard Worker     {
6697*8975f5c5SAndroid Build Coastguard Worker         return false;
6698*8975f5c5SAndroid Build Coastguard Worker     }
6699*8975f5c5SAndroid Build Coastguard Worker 
6700*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
6701*8975f5c5SAndroid Build Coastguard Worker 
6702*8975f5c5SAndroid Build Coastguard Worker     return true;
6703*8975f5c5SAndroid Build Coastguard Worker }
6704*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetVertexAttribPointervRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,void * const * pointer)6705*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribPointervRobustANGLE(const Context *context,
6706*8975f5c5SAndroid Build Coastguard Worker                                                 angle::EntryPoint entryPoint,
6707*8975f5c5SAndroid Build Coastguard Worker                                                 GLuint index,
6708*8975f5c5SAndroid Build Coastguard Worker                                                 GLenum pname,
6709*8975f5c5SAndroid Build Coastguard Worker                                                 GLsizei bufSize,
6710*8975f5c5SAndroid Build Coastguard Worker                                                 const GLsizei *length,
6711*8975f5c5SAndroid Build Coastguard Worker                                                 void *const *pointer)
6712*8975f5c5SAndroid Build Coastguard Worker {
6713*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6714*8975f5c5SAndroid Build Coastguard Worker     {
6715*8975f5c5SAndroid Build Coastguard Worker         return false;
6716*8975f5c5SAndroid Build Coastguard Worker     }
6717*8975f5c5SAndroid Build Coastguard Worker 
6718*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
6719*8975f5c5SAndroid Build Coastguard Worker 
6720*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, true, false))
6721*8975f5c5SAndroid Build Coastguard Worker     {
6722*8975f5c5SAndroid Build Coastguard Worker         return false;
6723*8975f5c5SAndroid Build Coastguard Worker     }
6724*8975f5c5SAndroid Build Coastguard Worker 
6725*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6726*8975f5c5SAndroid Build Coastguard Worker     {
6727*8975f5c5SAndroid Build Coastguard Worker         return false;
6728*8975f5c5SAndroid Build Coastguard Worker     }
6729*8975f5c5SAndroid Build Coastguard Worker 
6730*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
6731*8975f5c5SAndroid Build Coastguard Worker 
6732*8975f5c5SAndroid Build Coastguard Worker     return true;
6733*8975f5c5SAndroid Build Coastguard Worker }
6734*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetVertexAttribIivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6735*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribIivRobustANGLE(const Context *context,
6736*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint entryPoint,
6737*8975f5c5SAndroid Build Coastguard Worker                                            GLuint index,
6738*8975f5c5SAndroid Build Coastguard Worker                                            GLenum pname,
6739*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei bufSize,
6740*8975f5c5SAndroid Build Coastguard Worker                                            const GLsizei *length,
6741*8975f5c5SAndroid Build Coastguard Worker                                            const GLint *params)
6742*8975f5c5SAndroid Build Coastguard Worker {
6743*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6744*8975f5c5SAndroid Build Coastguard Worker     {
6745*8975f5c5SAndroid Build Coastguard Worker         return false;
6746*8975f5c5SAndroid Build Coastguard Worker     }
6747*8975f5c5SAndroid Build Coastguard Worker 
6748*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
6749*8975f5c5SAndroid Build Coastguard Worker 
6750*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true))
6751*8975f5c5SAndroid Build Coastguard Worker     {
6752*8975f5c5SAndroid Build Coastguard Worker         return false;
6753*8975f5c5SAndroid Build Coastguard Worker     }
6754*8975f5c5SAndroid Build Coastguard Worker 
6755*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6756*8975f5c5SAndroid Build Coastguard Worker     {
6757*8975f5c5SAndroid Build Coastguard Worker         return false;
6758*8975f5c5SAndroid Build Coastguard Worker     }
6759*8975f5c5SAndroid Build Coastguard Worker 
6760*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
6761*8975f5c5SAndroid Build Coastguard Worker 
6762*8975f5c5SAndroid Build Coastguard Worker     return true;
6763*8975f5c5SAndroid Build Coastguard Worker }
6764*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetVertexAttribIuivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLuint * params)6765*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribIuivRobustANGLE(const Context *context,
6766*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
6767*8975f5c5SAndroid Build Coastguard Worker                                             GLuint index,
6768*8975f5c5SAndroid Build Coastguard Worker                                             GLenum pname,
6769*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei bufSize,
6770*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei *length,
6771*8975f5c5SAndroid Build Coastguard Worker                                             const GLuint *params)
6772*8975f5c5SAndroid Build Coastguard Worker {
6773*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6774*8975f5c5SAndroid Build Coastguard Worker     {
6775*8975f5c5SAndroid Build Coastguard Worker         return false;
6776*8975f5c5SAndroid Build Coastguard Worker     }
6777*8975f5c5SAndroid Build Coastguard Worker 
6778*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
6779*8975f5c5SAndroid Build Coastguard Worker 
6780*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetVertexAttribBase(context, entryPoint, index, pname, &writeLength, false, true))
6781*8975f5c5SAndroid Build Coastguard Worker     {
6782*8975f5c5SAndroid Build Coastguard Worker         return false;
6783*8975f5c5SAndroid Build Coastguard Worker     }
6784*8975f5c5SAndroid Build Coastguard Worker 
6785*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6786*8975f5c5SAndroid Build Coastguard Worker     {
6787*8975f5c5SAndroid Build Coastguard Worker         return false;
6788*8975f5c5SAndroid Build Coastguard Worker     }
6789*8975f5c5SAndroid Build Coastguard Worker 
6790*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
6791*8975f5c5SAndroid Build Coastguard Worker 
6792*8975f5c5SAndroid Build Coastguard Worker     return true;
6793*8975f5c5SAndroid Build Coastguard Worker }
6794*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetActiveUniformBlockivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6795*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetActiveUniformBlockivRobustANGLE(const Context *context,
6796*8975f5c5SAndroid Build Coastguard Worker                                                 angle::EntryPoint entryPoint,
6797*8975f5c5SAndroid Build Coastguard Worker                                                 ShaderProgramID program,
6798*8975f5c5SAndroid Build Coastguard Worker                                                 UniformBlockIndex uniformBlockIndex,
6799*8975f5c5SAndroid Build Coastguard Worker                                                 GLenum pname,
6800*8975f5c5SAndroid Build Coastguard Worker                                                 GLsizei bufSize,
6801*8975f5c5SAndroid Build Coastguard Worker                                                 const GLsizei *length,
6802*8975f5c5SAndroid Build Coastguard Worker                                                 const GLint *params)
6803*8975f5c5SAndroid Build Coastguard Worker {
6804*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6805*8975f5c5SAndroid Build Coastguard Worker     {
6806*8975f5c5SAndroid Build Coastguard Worker         return false;
6807*8975f5c5SAndroid Build Coastguard Worker     }
6808*8975f5c5SAndroid Build Coastguard Worker 
6809*8975f5c5SAndroid Build Coastguard Worker     GLsizei writeLength = 0;
6810*8975f5c5SAndroid Build Coastguard Worker 
6811*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex, pname,
6812*8975f5c5SAndroid Build Coastguard Worker                                              &writeLength))
6813*8975f5c5SAndroid Build Coastguard Worker     {
6814*8975f5c5SAndroid Build Coastguard Worker         return false;
6815*8975f5c5SAndroid Build Coastguard Worker     }
6816*8975f5c5SAndroid Build Coastguard Worker 
6817*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, writeLength))
6818*8975f5c5SAndroid Build Coastguard Worker     {
6819*8975f5c5SAndroid Build Coastguard Worker         return false;
6820*8975f5c5SAndroid Build Coastguard Worker     }
6821*8975f5c5SAndroid Build Coastguard Worker 
6822*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, writeLength);
6823*8975f5c5SAndroid Build Coastguard Worker 
6824*8975f5c5SAndroid Build Coastguard Worker     return true;
6825*8975f5c5SAndroid Build Coastguard Worker }
6826*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetInternalformativRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)6827*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetInternalformativRobustANGLE(const Context *context,
6828*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
6829*8975f5c5SAndroid Build Coastguard Worker                                             GLenum target,
6830*8975f5c5SAndroid Build Coastguard Worker                                             GLenum internalformat,
6831*8975f5c5SAndroid Build Coastguard Worker                                             GLenum pname,
6832*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei bufSize,
6833*8975f5c5SAndroid Build Coastguard Worker                                             const GLsizei *length,
6834*8975f5c5SAndroid Build Coastguard Worker                                             const GLint *params)
6835*8975f5c5SAndroid Build Coastguard Worker {
6836*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
6837*8975f5c5SAndroid Build Coastguard Worker     {
6838*8975f5c5SAndroid Build Coastguard Worker         return false;
6839*8975f5c5SAndroid Build Coastguard Worker     }
6840*8975f5c5SAndroid Build Coastguard Worker 
6841*8975f5c5SAndroid Build Coastguard Worker     GLsizei numParams = 0;
6842*8975f5c5SAndroid Build Coastguard Worker 
6843*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname,
6844*8975f5c5SAndroid Build Coastguard Worker                                          bufSize, &numParams))
6845*8975f5c5SAndroid Build Coastguard Worker     {
6846*8975f5c5SAndroid Build Coastguard Worker         return false;
6847*8975f5c5SAndroid Build Coastguard Worker     }
6848*8975f5c5SAndroid Build Coastguard Worker 
6849*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
6850*8975f5c5SAndroid Build Coastguard Worker     {
6851*8975f5c5SAndroid Build Coastguard Worker         return false;
6852*8975f5c5SAndroid Build Coastguard Worker     }
6853*8975f5c5SAndroid Build Coastguard Worker 
6854*8975f5c5SAndroid Build Coastguard Worker     SetRobustLengthParam(length, numParams);
6855*8975f5c5SAndroid Build Coastguard Worker 
6856*8975f5c5SAndroid Build Coastguard Worker     return true;
6857*8975f5c5SAndroid Build Coastguard Worker }
6858*8975f5c5SAndroid Build Coastguard Worker 
ValidateRobustCompressedTexImageBase(const Context * context,angle::EntryPoint entryPoint,GLsizei imageSize,GLsizei dataSize)6859*8975f5c5SAndroid Build Coastguard Worker bool ValidateRobustCompressedTexImageBase(const Context *context,
6860*8975f5c5SAndroid Build Coastguard Worker                                           angle::EntryPoint entryPoint,
6861*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei imageSize,
6862*8975f5c5SAndroid Build Coastguard Worker                                           GLsizei dataSize)
6863*8975f5c5SAndroid Build Coastguard Worker {
6864*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateRobustEntryPoint(context, entryPoint, dataSize))
6865*8975f5c5SAndroid Build Coastguard Worker     {
6866*8975f5c5SAndroid Build Coastguard Worker         return false;
6867*8975f5c5SAndroid Build Coastguard Worker     }
6868*8975f5c5SAndroid Build Coastguard Worker 
6869*8975f5c5SAndroid Build Coastguard Worker     Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
6870*8975f5c5SAndroid Build Coastguard Worker     if (pixelUnpackBuffer == nullptr)
6871*8975f5c5SAndroid Build Coastguard Worker     {
6872*8975f5c5SAndroid Build Coastguard Worker         if (dataSize < imageSize)
6873*8975f5c5SAndroid Build Coastguard Worker         {
6874*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
6875*8975f5c5SAndroid Build Coastguard Worker         }
6876*8975f5c5SAndroid Build Coastguard Worker     }
6877*8975f5c5SAndroid Build Coastguard Worker     return true;
6878*8975f5c5SAndroid Build Coastguard Worker }
6879*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetBufferParameterBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,bool pointerVersion,GLsizei * numParams)6880*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetBufferParameterBase(const Context *context,
6881*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
6882*8975f5c5SAndroid Build Coastguard Worker                                     BufferBinding target,
6883*8975f5c5SAndroid Build Coastguard Worker                                     GLenum pname,
6884*8975f5c5SAndroid Build Coastguard Worker                                     bool pointerVersion,
6885*8975f5c5SAndroid Build Coastguard Worker                                     GLsizei *numParams)
6886*8975f5c5SAndroid Build Coastguard Worker {
6887*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
6888*8975f5c5SAndroid Build Coastguard Worker     {
6889*8975f5c5SAndroid Build Coastguard Worker         *numParams = 0;
6890*8975f5c5SAndroid Build Coastguard Worker     }
6891*8975f5c5SAndroid Build Coastguard Worker 
6892*8975f5c5SAndroid Build Coastguard Worker     if (!context->isValidBufferBinding(target))
6893*8975f5c5SAndroid Build Coastguard Worker     {
6894*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
6895*8975f5c5SAndroid Build Coastguard Worker         return false;
6896*8975f5c5SAndroid Build Coastguard Worker     }
6897*8975f5c5SAndroid Build Coastguard Worker 
6898*8975f5c5SAndroid Build Coastguard Worker     const Buffer *buffer = context->getState().getTargetBuffer(target);
6899*8975f5c5SAndroid Build Coastguard Worker     if (!buffer)
6900*8975f5c5SAndroid Build Coastguard Worker     {
6901*8975f5c5SAndroid Build Coastguard Worker         // A null buffer means that "0" is bound to the requested buffer target
6902*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
6903*8975f5c5SAndroid Build Coastguard Worker         return false;
6904*8975f5c5SAndroid Build Coastguard Worker     }
6905*8975f5c5SAndroid Build Coastguard Worker 
6906*8975f5c5SAndroid Build Coastguard Worker     const Extensions &extensions = context->getExtensions();
6907*8975f5c5SAndroid Build Coastguard Worker 
6908*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
6909*8975f5c5SAndroid Build Coastguard Worker     {
6910*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_USAGE:
6911*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_SIZE:
6912*8975f5c5SAndroid Build Coastguard Worker             break;
6913*8975f5c5SAndroid Build Coastguard Worker 
6914*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_ACCESS_OES:
6915*8975f5c5SAndroid Build Coastguard Worker             if (!extensions.mapbufferOES)
6916*8975f5c5SAndroid Build Coastguard Worker             {
6917*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6918*8975f5c5SAndroid Build Coastguard Worker                 return false;
6919*8975f5c5SAndroid Build Coastguard Worker             }
6920*8975f5c5SAndroid Build Coastguard Worker             break;
6921*8975f5c5SAndroid Build Coastguard Worker 
6922*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_MAPPED:
6923*8975f5c5SAndroid Build Coastguard Worker             static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
6924*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 && !extensions.mapbufferOES &&
6925*8975f5c5SAndroid Build Coastguard Worker                 !extensions.mapBufferRangeEXT)
6926*8975f5c5SAndroid Build Coastguard Worker             {
6927*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6928*8975f5c5SAndroid Build Coastguard Worker                 return false;
6929*8975f5c5SAndroid Build Coastguard Worker             }
6930*8975f5c5SAndroid Build Coastguard Worker             break;
6931*8975f5c5SAndroid Build Coastguard Worker 
6932*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_MAP_POINTER:
6933*8975f5c5SAndroid Build Coastguard Worker             if (!pointerVersion)
6934*8975f5c5SAndroid Build Coastguard Worker             {
6935*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMapPointerQuery);
6936*8975f5c5SAndroid Build Coastguard Worker                 return false;
6937*8975f5c5SAndroid Build Coastguard Worker             }
6938*8975f5c5SAndroid Build Coastguard Worker             break;
6939*8975f5c5SAndroid Build Coastguard Worker 
6940*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_ACCESS_FLAGS:
6941*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_MAP_OFFSET:
6942*8975f5c5SAndroid Build Coastguard Worker         case GL_BUFFER_MAP_LENGTH:
6943*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRangeEXT)
6944*8975f5c5SAndroid Build Coastguard Worker             {
6945*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6946*8975f5c5SAndroid Build Coastguard Worker                 return false;
6947*8975f5c5SAndroid Build Coastguard Worker             }
6948*8975f5c5SAndroid Build Coastguard Worker             break;
6949*8975f5c5SAndroid Build Coastguard Worker 
6950*8975f5c5SAndroid Build Coastguard Worker         case GL_MEMORY_SIZE_ANGLE:
6951*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().memorySizeANGLE)
6952*8975f5c5SAndroid Build Coastguard Worker             {
6953*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
6954*8975f5c5SAndroid Build Coastguard Worker                 return false;
6955*8975f5c5SAndroid Build Coastguard Worker             }
6956*8975f5c5SAndroid Build Coastguard Worker             break;
6957*8975f5c5SAndroid Build Coastguard Worker 
6958*8975f5c5SAndroid Build Coastguard Worker         case GL_RESOURCE_INITIALIZED_ANGLE:
6959*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().robustResourceInitializationANGLE)
6960*8975f5c5SAndroid Build Coastguard Worker             {
6961*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
6962*8975f5c5SAndroid Build Coastguard Worker                                        kRobustResourceInitializationExtensionRequired);
6963*8975f5c5SAndroid Build Coastguard Worker                 return false;
6964*8975f5c5SAndroid Build Coastguard Worker             }
6965*8975f5c5SAndroid Build Coastguard Worker             break;
6966*8975f5c5SAndroid Build Coastguard Worker 
6967*8975f5c5SAndroid Build Coastguard Worker         default:
6968*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
6969*8975f5c5SAndroid Build Coastguard Worker             return false;
6970*8975f5c5SAndroid Build Coastguard Worker     }
6971*8975f5c5SAndroid Build Coastguard Worker 
6972*8975f5c5SAndroid Build Coastguard Worker     // All buffer parameter queries return one value.
6973*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
6974*8975f5c5SAndroid Build Coastguard Worker     {
6975*8975f5c5SAndroid Build Coastguard Worker         *numParams = 1;
6976*8975f5c5SAndroid Build Coastguard Worker     }
6977*8975f5c5SAndroid Build Coastguard Worker 
6978*8975f5c5SAndroid Build Coastguard Worker     return true;
6979*8975f5c5SAndroid Build Coastguard Worker }
6980*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetRenderbufferParameterivBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLsizei * length)6981*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetRenderbufferParameterivBase(const Context *context,
6982*8975f5c5SAndroid Build Coastguard Worker                                             angle::EntryPoint entryPoint,
6983*8975f5c5SAndroid Build Coastguard Worker                                             GLenum target,
6984*8975f5c5SAndroid Build Coastguard Worker                                             GLenum pname,
6985*8975f5c5SAndroid Build Coastguard Worker                                             GLsizei *length)
6986*8975f5c5SAndroid Build Coastguard Worker {
6987*8975f5c5SAndroid Build Coastguard Worker     if (length)
6988*8975f5c5SAndroid Build Coastguard Worker     {
6989*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
6990*8975f5c5SAndroid Build Coastguard Worker     }
6991*8975f5c5SAndroid Build Coastguard Worker 
6992*8975f5c5SAndroid Build Coastguard Worker     if (target != GL_RENDERBUFFER)
6993*8975f5c5SAndroid Build Coastguard Worker     {
6994*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
6995*8975f5c5SAndroid Build Coastguard Worker         return false;
6996*8975f5c5SAndroid Build Coastguard Worker     }
6997*8975f5c5SAndroid Build Coastguard Worker 
6998*8975f5c5SAndroid Build Coastguard Worker     Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
6999*8975f5c5SAndroid Build Coastguard Worker     if (renderbuffer == nullptr)
7000*8975f5c5SAndroid Build Coastguard Worker     {
7001*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kRenderbufferNotBound);
7002*8975f5c5SAndroid Build Coastguard Worker         return false;
7003*8975f5c5SAndroid Build Coastguard Worker     }
7004*8975f5c5SAndroid Build Coastguard Worker 
7005*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
7006*8975f5c5SAndroid Build Coastguard Worker     {
7007*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_WIDTH:
7008*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_HEIGHT:
7009*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_INTERNAL_FORMAT:
7010*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_RED_SIZE:
7011*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_GREEN_SIZE:
7012*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_BLUE_SIZE:
7013*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_ALPHA_SIZE:
7014*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_DEPTH_SIZE:
7015*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_STENCIL_SIZE:
7016*8975f5c5SAndroid Build Coastguard Worker             break;
7017*8975f5c5SAndroid Build Coastguard Worker 
7018*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER_SAMPLES_ANGLE:
7019*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 &&
7020*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().framebufferMultisampleANGLE)
7021*8975f5c5SAndroid Build Coastguard Worker             {
7022*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7023*8975f5c5SAndroid Build Coastguard Worker                 return false;
7024*8975f5c5SAndroid Build Coastguard Worker             }
7025*8975f5c5SAndroid Build Coastguard Worker             break;
7026*8975f5c5SAndroid Build Coastguard Worker 
7027*8975f5c5SAndroid Build Coastguard Worker         case GL_MEMORY_SIZE_ANGLE:
7028*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().memorySizeANGLE)
7029*8975f5c5SAndroid Build Coastguard Worker             {
7030*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7031*8975f5c5SAndroid Build Coastguard Worker                 return false;
7032*8975f5c5SAndroid Build Coastguard Worker             }
7033*8975f5c5SAndroid Build Coastguard Worker             break;
7034*8975f5c5SAndroid Build Coastguard Worker 
7035*8975f5c5SAndroid Build Coastguard Worker         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
7036*8975f5c5SAndroid Build Coastguard Worker         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
7037*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().getImageANGLE)
7038*8975f5c5SAndroid Build Coastguard Worker             {
7039*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGetImageExtensionNotEnabled);
7040*8975f5c5SAndroid Build Coastguard Worker                 return false;
7041*8975f5c5SAndroid Build Coastguard Worker             }
7042*8975f5c5SAndroid Build Coastguard Worker             break;
7043*8975f5c5SAndroid Build Coastguard Worker 
7044*8975f5c5SAndroid Build Coastguard Worker         case GL_RESOURCE_INITIALIZED_ANGLE:
7045*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().robustResourceInitializationANGLE)
7046*8975f5c5SAndroid Build Coastguard Worker             {
7047*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
7048*8975f5c5SAndroid Build Coastguard Worker                                        kRobustResourceInitializationExtensionRequired);
7049*8975f5c5SAndroid Build Coastguard Worker                 return false;
7050*8975f5c5SAndroid Build Coastguard Worker             }
7051*8975f5c5SAndroid Build Coastguard Worker             break;
7052*8975f5c5SAndroid Build Coastguard Worker 
7053*8975f5c5SAndroid Build Coastguard Worker         default:
7054*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7055*8975f5c5SAndroid Build Coastguard Worker             return false;
7056*8975f5c5SAndroid Build Coastguard Worker     }
7057*8975f5c5SAndroid Build Coastguard Worker 
7058*8975f5c5SAndroid Build Coastguard Worker     if (length)
7059*8975f5c5SAndroid Build Coastguard Worker     {
7060*8975f5c5SAndroid Build Coastguard Worker         *length = 1;
7061*8975f5c5SAndroid Build Coastguard Worker     }
7062*8975f5c5SAndroid Build Coastguard Worker     return true;
7063*8975f5c5SAndroid Build Coastguard Worker }
7064*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetShaderivBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLenum pname,GLsizei * length)7065*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetShaderivBase(const Context *context,
7066*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
7067*8975f5c5SAndroid Build Coastguard Worker                              ShaderProgramID shader,
7068*8975f5c5SAndroid Build Coastguard Worker                              GLenum pname,
7069*8975f5c5SAndroid Build Coastguard Worker                              GLsizei *length)
7070*8975f5c5SAndroid Build Coastguard Worker {
7071*8975f5c5SAndroid Build Coastguard Worker     if (length)
7072*8975f5c5SAndroid Build Coastguard Worker     {
7073*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
7074*8975f5c5SAndroid Build Coastguard Worker     }
7075*8975f5c5SAndroid Build Coastguard Worker 
7076*8975f5c5SAndroid Build Coastguard Worker     if (context->isContextLost())
7077*8975f5c5SAndroid Build Coastguard Worker     {
7078*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
7079*8975f5c5SAndroid Build Coastguard Worker 
7080*8975f5c5SAndroid Build Coastguard Worker         if (context->getExtensions().parallelShaderCompileKHR && pname == GL_COMPLETION_STATUS_KHR)
7081*8975f5c5SAndroid Build Coastguard Worker         {
7082*8975f5c5SAndroid Build Coastguard Worker             // Generate an error but still return true, the context still needs to return a
7083*8975f5c5SAndroid Build Coastguard Worker             // value in this case.
7084*8975f5c5SAndroid Build Coastguard Worker             return true;
7085*8975f5c5SAndroid Build Coastguard Worker         }
7086*8975f5c5SAndroid Build Coastguard Worker         else
7087*8975f5c5SAndroid Build Coastguard Worker         {
7088*8975f5c5SAndroid Build Coastguard Worker             return false;
7089*8975f5c5SAndroid Build Coastguard Worker         }
7090*8975f5c5SAndroid Build Coastguard Worker     }
7091*8975f5c5SAndroid Build Coastguard Worker 
7092*8975f5c5SAndroid Build Coastguard Worker     if (GetValidShader(context, entryPoint, shader) == nullptr)
7093*8975f5c5SAndroid Build Coastguard Worker     {
7094*8975f5c5SAndroid Build Coastguard Worker         return false;
7095*8975f5c5SAndroid Build Coastguard Worker     }
7096*8975f5c5SAndroid Build Coastguard Worker 
7097*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
7098*8975f5c5SAndroid Build Coastguard Worker     {
7099*8975f5c5SAndroid Build Coastguard Worker         case GL_SHADER_TYPE:
7100*8975f5c5SAndroid Build Coastguard Worker         case GL_DELETE_STATUS:
7101*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPILE_STATUS:
7102*8975f5c5SAndroid Build Coastguard Worker         case GL_INFO_LOG_LENGTH:
7103*8975f5c5SAndroid Build Coastguard Worker         case GL_SHADER_SOURCE_LENGTH:
7104*8975f5c5SAndroid Build Coastguard Worker             break;
7105*8975f5c5SAndroid Build Coastguard Worker 
7106*8975f5c5SAndroid Build Coastguard Worker         case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
7107*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().translatedShaderSourceANGLE)
7108*8975f5c5SAndroid Build Coastguard Worker             {
7109*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7110*8975f5c5SAndroid Build Coastguard Worker                 return false;
7111*8975f5c5SAndroid Build Coastguard Worker             }
7112*8975f5c5SAndroid Build Coastguard Worker             break;
7113*8975f5c5SAndroid Build Coastguard Worker 
7114*8975f5c5SAndroid Build Coastguard Worker         case GL_COMPLETION_STATUS_KHR:
7115*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().parallelShaderCompileKHR)
7116*8975f5c5SAndroid Build Coastguard Worker             {
7117*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
7118*8975f5c5SAndroid Build Coastguard Worker                 return false;
7119*8975f5c5SAndroid Build Coastguard Worker             }
7120*8975f5c5SAndroid Build Coastguard Worker             break;
7121*8975f5c5SAndroid Build Coastguard Worker 
7122*8975f5c5SAndroid Build Coastguard Worker         default:
7123*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7124*8975f5c5SAndroid Build Coastguard Worker             return false;
7125*8975f5c5SAndroid Build Coastguard Worker     }
7126*8975f5c5SAndroid Build Coastguard Worker 
7127*8975f5c5SAndroid Build Coastguard Worker     if (length)
7128*8975f5c5SAndroid Build Coastguard Worker     {
7129*8975f5c5SAndroid Build Coastguard Worker         *length = 1;
7130*8975f5c5SAndroid Build Coastguard Worker     }
7131*8975f5c5SAndroid Build Coastguard Worker     return true;
7132*8975f5c5SAndroid Build Coastguard Worker }
7133*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetTexParameterBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei * length)7134*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexParameterBase(const Context *context,
7135*8975f5c5SAndroid Build Coastguard Worker                                  angle::EntryPoint entryPoint,
7136*8975f5c5SAndroid Build Coastguard Worker                                  TextureType target,
7137*8975f5c5SAndroid Build Coastguard Worker                                  GLenum pname,
7138*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei *length)
7139*8975f5c5SAndroid Build Coastguard Worker {
7140*8975f5c5SAndroid Build Coastguard Worker     if (length)
7141*8975f5c5SAndroid Build Coastguard Worker     {
7142*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
7143*8975f5c5SAndroid Build Coastguard Worker     }
7144*8975f5c5SAndroid Build Coastguard Worker 
7145*8975f5c5SAndroid Build Coastguard Worker     if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) ||
7146*8975f5c5SAndroid Build Coastguard Worker         target == TextureType::Buffer)
7147*8975f5c5SAndroid Build Coastguard Worker     {
7148*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
7149*8975f5c5SAndroid Build Coastguard Worker         return false;
7150*8975f5c5SAndroid Build Coastguard Worker     }
7151*8975f5c5SAndroid Build Coastguard Worker 
7152*8975f5c5SAndroid Build Coastguard Worker     if (context->getTextureByType(target) == nullptr)
7153*8975f5c5SAndroid Build Coastguard Worker     {
7154*8975f5c5SAndroid Build Coastguard Worker         // Should only be possible for external textures
7155*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureNotBound);
7156*8975f5c5SAndroid Build Coastguard Worker         return false;
7157*8975f5c5SAndroid Build Coastguard Worker     }
7158*8975f5c5SAndroid Build Coastguard Worker 
7159*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
7160*8975f5c5SAndroid Build Coastguard Worker     {
7161*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7162*8975f5c5SAndroid Build Coastguard Worker         return false;
7163*8975f5c5SAndroid Build Coastguard Worker     }
7164*8975f5c5SAndroid Build Coastguard Worker 
7165*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
7166*8975f5c5SAndroid Build Coastguard Worker     {
7167*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAG_FILTER:
7168*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_FILTER:
7169*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_S:
7170*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_T:
7171*8975f5c5SAndroid Build Coastguard Worker             break;
7172*8975f5c5SAndroid Build Coastguard Worker 
7173*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_USAGE_ANGLE:
7174*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureUsageANGLE)
7175*8975f5c5SAndroid Build Coastguard Worker             {
7176*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7177*8975f5c5SAndroid Build Coastguard Worker                 return false;
7178*8975f5c5SAndroid Build Coastguard Worker             }
7179*8975f5c5SAndroid Build Coastguard Worker             break;
7180*8975f5c5SAndroid Build Coastguard Worker 
7181*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
7182*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
7183*8975f5c5SAndroid Build Coastguard Worker             {
7184*8975f5c5SAndroid Build Coastguard Worker                 return false;
7185*8975f5c5SAndroid Build Coastguard Worker             }
7186*8975f5c5SAndroid Build Coastguard Worker             break;
7187*8975f5c5SAndroid Build Coastguard Worker 
7188*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_IMMUTABLE_FORMAT:
7189*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorageEXT)
7190*8975f5c5SAndroid Build Coastguard Worker             {
7191*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7192*8975f5c5SAndroid Build Coastguard Worker                 return false;
7193*8975f5c5SAndroid Build Coastguard Worker             }
7194*8975f5c5SAndroid Build Coastguard Worker             break;
7195*8975f5c5SAndroid Build Coastguard Worker 
7196*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_R:
7197*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_IMMUTABLE_LEVELS:
7198*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_R:
7199*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_G:
7200*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_B:
7201*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_A:
7202*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BASE_LEVEL:
7203*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LEVEL:
7204*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_LOD:
7205*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LOD:
7206*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3)
7207*8975f5c5SAndroid Build Coastguard Worker             {
7208*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES30);
7209*8975f5c5SAndroid Build Coastguard Worker                 return false;
7210*8975f5c5SAndroid Build Coastguard Worker             }
7211*8975f5c5SAndroid Build Coastguard Worker             break;
7212*8975f5c5SAndroid Build Coastguard Worker 
7213*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_MODE:
7214*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_FUNC:
7215*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 && !context->getExtensions().shadowSamplersEXT)
7216*8975f5c5SAndroid Build Coastguard Worker             {
7217*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7218*8975f5c5SAndroid Build Coastguard Worker                 return false;
7219*8975f5c5SAndroid Build Coastguard Worker             }
7220*8975f5c5SAndroid Build Coastguard Worker             break;
7221*8975f5c5SAndroid Build Coastguard Worker 
7222*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SRGB_DECODE_EXT:
7223*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureSRGBDecodeEXT)
7224*8975f5c5SAndroid Build Coastguard Worker             {
7225*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7226*8975f5c5SAndroid Build Coastguard Worker                 return false;
7227*8975f5c5SAndroid Build Coastguard Worker             }
7228*8975f5c5SAndroid Build Coastguard Worker             break;
7229*8975f5c5SAndroid Build Coastguard Worker 
7230*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_STENCIL_TEXTURE_MODE:
7231*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_1 &&
7232*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().stencilTexturingANGLE)
7233*8975f5c5SAndroid Build Coastguard Worker             {
7234*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7235*8975f5c5SAndroid Build Coastguard Worker                 return false;
7236*8975f5c5SAndroid Build Coastguard Worker             }
7237*8975f5c5SAndroid Build Coastguard Worker             break;
7238*8975f5c5SAndroid Build Coastguard Worker 
7239*8975f5c5SAndroid Build Coastguard Worker         case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
7240*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_1)
7241*8975f5c5SAndroid Build Coastguard Worker             {
7242*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
7243*8975f5c5SAndroid Build Coastguard Worker                 return false;
7244*8975f5c5SAndroid Build Coastguard Worker             }
7245*8975f5c5SAndroid Build Coastguard Worker             break;
7246*8975f5c5SAndroid Build Coastguard Worker 
7247*8975f5c5SAndroid Build Coastguard Worker         case GL_GENERATE_MIPMAP:
7248*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CROP_RECT_OES:
7249*8975f5c5SAndroid Build Coastguard Worker             // TODO([email protected]): Restrict to GL_OES_draw_texture
7250*8975f5c5SAndroid Build Coastguard Worker             // after GL_OES_draw_texture functionality implemented
7251*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() > 1)
7252*8975f5c5SAndroid Build Coastguard Worker             {
7253*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
7254*8975f5c5SAndroid Build Coastguard Worker                 return false;
7255*8975f5c5SAndroid Build Coastguard Worker             }
7256*8975f5c5SAndroid Build Coastguard Worker             break;
7257*8975f5c5SAndroid Build Coastguard Worker 
7258*8975f5c5SAndroid Build Coastguard Worker         case GL_MEMORY_SIZE_ANGLE:
7259*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().memorySizeANGLE)
7260*8975f5c5SAndroid Build Coastguard Worker             {
7261*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7262*8975f5c5SAndroid Build Coastguard Worker                 return false;
7263*8975f5c5SAndroid Build Coastguard Worker             }
7264*8975f5c5SAndroid Build Coastguard Worker             break;
7265*8975f5c5SAndroid Build Coastguard Worker 
7266*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BORDER_COLOR:
7267*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureBorderClampAny() &&
7268*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
7269*8975f5c5SAndroid Build Coastguard Worker             {
7270*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7271*8975f5c5SAndroid Build Coastguard Worker                 return false;
7272*8975f5c5SAndroid Build Coastguard Worker             }
7273*8975f5c5SAndroid Build Coastguard Worker             break;
7274*8975f5c5SAndroid Build Coastguard Worker 
7275*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_NATIVE_ID_ANGLE:
7276*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureExternalUpdateANGLE)
7277*8975f5c5SAndroid Build Coastguard Worker             {
7278*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
7279*8975f5c5SAndroid Build Coastguard Worker                 return false;
7280*8975f5c5SAndroid Build Coastguard Worker             }
7281*8975f5c5SAndroid Build Coastguard Worker             break;
7282*8975f5c5SAndroid Build Coastguard Worker 
7283*8975f5c5SAndroid Build Coastguard Worker         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
7284*8975f5c5SAndroid Build Coastguard Worker         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
7285*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().getImageANGLE)
7286*8975f5c5SAndroid Build Coastguard Worker             {
7287*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGetImageExtensionNotEnabled);
7288*8975f5c5SAndroid Build Coastguard Worker                 return false;
7289*8975f5c5SAndroid Build Coastguard Worker             }
7290*8975f5c5SAndroid Build Coastguard Worker             break;
7291*8975f5c5SAndroid Build Coastguard Worker 
7292*8975f5c5SAndroid Build Coastguard Worker         case GL_RESOURCE_INITIALIZED_ANGLE:
7293*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().robustResourceInitializationANGLE)
7294*8975f5c5SAndroid Build Coastguard Worker             {
7295*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
7296*8975f5c5SAndroid Build Coastguard Worker                                        kRobustResourceInitializationExtensionRequired);
7297*8975f5c5SAndroid Build Coastguard Worker                 return false;
7298*8975f5c5SAndroid Build Coastguard Worker             }
7299*8975f5c5SAndroid Build Coastguard Worker             break;
7300*8975f5c5SAndroid Build Coastguard Worker 
7301*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_PROTECTED_EXT:
7302*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().protectedTexturesEXT)
7303*8975f5c5SAndroid Build Coastguard Worker             {
7304*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProtectedTexturesExtensionRequired);
7305*8975f5c5SAndroid Build Coastguard Worker                 return false;
7306*8975f5c5SAndroid Build Coastguard Worker             }
7307*8975f5c5SAndroid Build Coastguard Worker             break;
7308*8975f5c5SAndroid Build Coastguard Worker 
7309*8975f5c5SAndroid Build Coastguard Worker         case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
7310*8975f5c5SAndroid Build Coastguard Worker             break;
7311*8975f5c5SAndroid Build Coastguard Worker 
7312*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM:
7313*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureFoveatedQCOM)
7314*8975f5c5SAndroid Build Coastguard Worker             {
7315*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
7316*8975f5c5SAndroid Build Coastguard Worker                 return false;
7317*8975f5c5SAndroid Build Coastguard Worker             }
7318*8975f5c5SAndroid Build Coastguard Worker             break;
7319*8975f5c5SAndroid Build Coastguard Worker 
7320*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM:
7321*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureFoveatedQCOM)
7322*8975f5c5SAndroid Build Coastguard Worker             {
7323*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
7324*8975f5c5SAndroid Build Coastguard Worker                 return false;
7325*8975f5c5SAndroid Build Coastguard Worker             }
7326*8975f5c5SAndroid Build Coastguard Worker             break;
7327*8975f5c5SAndroid Build Coastguard Worker 
7328*8975f5c5SAndroid Build Coastguard Worker         case GL_SURFACE_COMPRESSION_EXT:
7329*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureStorageCompressionEXT)
7330*8975f5c5SAndroid Build Coastguard Worker             {
7331*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
7332*8975f5c5SAndroid Build Coastguard Worker                                        kTextureStorageCompressionExtensionRequired);
7333*8975f5c5SAndroid Build Coastguard Worker                 return false;
7334*8975f5c5SAndroid Build Coastguard Worker             }
7335*8975f5c5SAndroid Build Coastguard Worker             break;
7336*8975f5c5SAndroid Build Coastguard Worker 
7337*8975f5c5SAndroid Build Coastguard Worker         default:
7338*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7339*8975f5c5SAndroid Build Coastguard Worker             return false;
7340*8975f5c5SAndroid Build Coastguard Worker     }
7341*8975f5c5SAndroid Build Coastguard Worker 
7342*8975f5c5SAndroid Build Coastguard Worker     if (length)
7343*8975f5c5SAndroid Build Coastguard Worker     {
7344*8975f5c5SAndroid Build Coastguard Worker         *length = GetTexParameterCount(pname);
7345*8975f5c5SAndroid Build Coastguard Worker     }
7346*8975f5c5SAndroid Build Coastguard Worker     return true;
7347*8975f5c5SAndroid Build Coastguard Worker }
7348*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetVertexAttribBase(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,GLsizei * length,bool pointer,bool pureIntegerEntryPoint)7349*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetVertexAttribBase(const Context *context,
7350*8975f5c5SAndroid Build Coastguard Worker                                  angle::EntryPoint entryPoint,
7351*8975f5c5SAndroid Build Coastguard Worker                                  GLuint index,
7352*8975f5c5SAndroid Build Coastguard Worker                                  GLenum pname,
7353*8975f5c5SAndroid Build Coastguard Worker                                  GLsizei *length,
7354*8975f5c5SAndroid Build Coastguard Worker                                  bool pointer,
7355*8975f5c5SAndroid Build Coastguard Worker                                  bool pureIntegerEntryPoint)
7356*8975f5c5SAndroid Build Coastguard Worker {
7357*8975f5c5SAndroid Build Coastguard Worker     if (length)
7358*8975f5c5SAndroid Build Coastguard Worker     {
7359*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
7360*8975f5c5SAndroid Build Coastguard Worker     }
7361*8975f5c5SAndroid Build Coastguard Worker 
7362*8975f5c5SAndroid Build Coastguard Worker     if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
7363*8975f5c5SAndroid Build Coastguard Worker     {
7364*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
7365*8975f5c5SAndroid Build Coastguard Worker         return false;
7366*8975f5c5SAndroid Build Coastguard Worker     }
7367*8975f5c5SAndroid Build Coastguard Worker 
7368*8975f5c5SAndroid Build Coastguard Worker     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
7369*8975f5c5SAndroid Build Coastguard Worker     {
7370*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
7371*8975f5c5SAndroid Build Coastguard Worker         return false;
7372*8975f5c5SAndroid Build Coastguard Worker     }
7373*8975f5c5SAndroid Build Coastguard Worker 
7374*8975f5c5SAndroid Build Coastguard Worker     if (pointer)
7375*8975f5c5SAndroid Build Coastguard Worker     {
7376*8975f5c5SAndroid Build Coastguard Worker         if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
7377*8975f5c5SAndroid Build Coastguard Worker         {
7378*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7379*8975f5c5SAndroid Build Coastguard Worker             return false;
7380*8975f5c5SAndroid Build Coastguard Worker         }
7381*8975f5c5SAndroid Build Coastguard Worker     }
7382*8975f5c5SAndroid Build Coastguard Worker     else
7383*8975f5c5SAndroid Build Coastguard Worker     {
7384*8975f5c5SAndroid Build Coastguard Worker         switch (pname)
7385*8975f5c5SAndroid Build Coastguard Worker         {
7386*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
7387*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_SIZE:
7388*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
7389*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_TYPE:
7390*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
7391*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
7392*8975f5c5SAndroid Build Coastguard Worker             case GL_CURRENT_VERTEX_ATTRIB:
7393*8975f5c5SAndroid Build Coastguard Worker                 break;
7394*8975f5c5SAndroid Build Coastguard Worker 
7395*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
7396*8975f5c5SAndroid Build Coastguard Worker                 static_assert(
7397*8975f5c5SAndroid Build Coastguard Worker                     GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
7398*8975f5c5SAndroid Build Coastguard Worker                     "ANGLE extension enums not equal to GL enums.");
7399*8975f5c5SAndroid Build Coastguard Worker                 if (context->getClientMajorVersion() < 3 &&
7400*8975f5c5SAndroid Build Coastguard Worker                     !context->getExtensions().instancedArraysAny())
7401*8975f5c5SAndroid Build Coastguard Worker                 {
7402*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7403*8975f5c5SAndroid Build Coastguard Worker                     return false;
7404*8975f5c5SAndroid Build Coastguard Worker                 }
7405*8975f5c5SAndroid Build Coastguard Worker                 break;
7406*8975f5c5SAndroid Build Coastguard Worker 
7407*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
7408*8975f5c5SAndroid Build Coastguard Worker                 if (context->getClientMajorVersion() < 3)
7409*8975f5c5SAndroid Build Coastguard Worker                 {
7410*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7411*8975f5c5SAndroid Build Coastguard Worker                     return false;
7412*8975f5c5SAndroid Build Coastguard Worker                 }
7413*8975f5c5SAndroid Build Coastguard Worker                 break;
7414*8975f5c5SAndroid Build Coastguard Worker 
7415*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_BINDING:
7416*8975f5c5SAndroid Build Coastguard Worker             case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
7417*8975f5c5SAndroid Build Coastguard Worker                 if (context->getClientVersion() < ES_3_1)
7418*8975f5c5SAndroid Build Coastguard Worker                 {
7419*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
7420*8975f5c5SAndroid Build Coastguard Worker                     return false;
7421*8975f5c5SAndroid Build Coastguard Worker                 }
7422*8975f5c5SAndroid Build Coastguard Worker                 break;
7423*8975f5c5SAndroid Build Coastguard Worker 
7424*8975f5c5SAndroid Build Coastguard Worker             default:
7425*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7426*8975f5c5SAndroid Build Coastguard Worker                 return false;
7427*8975f5c5SAndroid Build Coastguard Worker         }
7428*8975f5c5SAndroid Build Coastguard Worker     }
7429*8975f5c5SAndroid Build Coastguard Worker 
7430*8975f5c5SAndroid Build Coastguard Worker     if (length)
7431*8975f5c5SAndroid Build Coastguard Worker     {
7432*8975f5c5SAndroid Build Coastguard Worker         if (pname == GL_CURRENT_VERTEX_ATTRIB)
7433*8975f5c5SAndroid Build Coastguard Worker         {
7434*8975f5c5SAndroid Build Coastguard Worker             *length = 4;
7435*8975f5c5SAndroid Build Coastguard Worker         }
7436*8975f5c5SAndroid Build Coastguard Worker         else
7437*8975f5c5SAndroid Build Coastguard Worker         {
7438*8975f5c5SAndroid Build Coastguard Worker             *length = 1;
7439*8975f5c5SAndroid Build Coastguard Worker         }
7440*8975f5c5SAndroid Build Coastguard Worker     }
7441*8975f5c5SAndroid Build Coastguard Worker 
7442*8975f5c5SAndroid Build Coastguard Worker     return true;
7443*8975f5c5SAndroid Build Coastguard Worker }
7444*8975f5c5SAndroid Build Coastguard Worker 
ValidatePixelPack(const Context * context,angle::EntryPoint entryPoint,GLenum format,GLenum type,GLint x,GLint y,GLsizei width,GLsizei height,GLsizei bufSize,GLsizei * length,const void * pixels)7445*8975f5c5SAndroid Build Coastguard Worker bool ValidatePixelPack(const Context *context,
7446*8975f5c5SAndroid Build Coastguard Worker                        angle::EntryPoint entryPoint,
7447*8975f5c5SAndroid Build Coastguard Worker                        GLenum format,
7448*8975f5c5SAndroid Build Coastguard Worker                        GLenum type,
7449*8975f5c5SAndroid Build Coastguard Worker                        GLint x,
7450*8975f5c5SAndroid Build Coastguard Worker                        GLint y,
7451*8975f5c5SAndroid Build Coastguard Worker                        GLsizei width,
7452*8975f5c5SAndroid Build Coastguard Worker                        GLsizei height,
7453*8975f5c5SAndroid Build Coastguard Worker                        GLsizei bufSize,
7454*8975f5c5SAndroid Build Coastguard Worker                        GLsizei *length,
7455*8975f5c5SAndroid Build Coastguard Worker                        const void *pixels)
7456*8975f5c5SAndroid Build Coastguard Worker {
7457*8975f5c5SAndroid Build Coastguard Worker     // Check for pixel pack buffer related API errors
7458*8975f5c5SAndroid Build Coastguard Worker     Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack);
7459*8975f5c5SAndroid Build Coastguard Worker     if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
7460*8975f5c5SAndroid Build Coastguard Worker     {
7461*8975f5c5SAndroid Build Coastguard Worker         // ...the buffer object's data store is currently mapped.
7462*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferMapped);
7463*8975f5c5SAndroid Build Coastguard Worker         return false;
7464*8975f5c5SAndroid Build Coastguard Worker     }
7465*8975f5c5SAndroid Build Coastguard Worker     if (pixelPackBuffer != nullptr &&
7466*8975f5c5SAndroid Build Coastguard Worker         pixelPackBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
7467*8975f5c5SAndroid Build Coastguard Worker     {
7468*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
7469*8975f5c5SAndroid Build Coastguard Worker         return false;
7470*8975f5c5SAndroid Build Coastguard Worker     }
7471*8975f5c5SAndroid Build Coastguard Worker 
7472*8975f5c5SAndroid Build Coastguard Worker     // ..  the data would be packed to the buffer object such that the memory writes required
7473*8975f5c5SAndroid Build Coastguard Worker     // would exceed the data store size.
7474*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
7475*8975f5c5SAndroid Build Coastguard Worker     const Extents size(width, height, 1);
7476*8975f5c5SAndroid Build Coastguard Worker     const auto &pack = context->getState().getPackState();
7477*8975f5c5SAndroid Build Coastguard Worker 
7478*8975f5c5SAndroid Build Coastguard Worker     GLuint endByte = 0;
7479*8975f5c5SAndroid Build Coastguard Worker     if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
7480*8975f5c5SAndroid Build Coastguard Worker     {
7481*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7482*8975f5c5SAndroid Build Coastguard Worker         return false;
7483*8975f5c5SAndroid Build Coastguard Worker     }
7484*8975f5c5SAndroid Build Coastguard Worker 
7485*8975f5c5SAndroid Build Coastguard Worker     if (bufSize >= 0)
7486*8975f5c5SAndroid Build Coastguard Worker     {
7487*8975f5c5SAndroid Build Coastguard Worker         if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
7488*8975f5c5SAndroid Build Coastguard Worker         {
7489*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
7490*8975f5c5SAndroid Build Coastguard Worker             return false;
7491*8975f5c5SAndroid Build Coastguard Worker         }
7492*8975f5c5SAndroid Build Coastguard Worker     }
7493*8975f5c5SAndroid Build Coastguard Worker 
7494*8975f5c5SAndroid Build Coastguard Worker     if (pixelPackBuffer != nullptr)
7495*8975f5c5SAndroid Build Coastguard Worker     {
7496*8975f5c5SAndroid Build Coastguard Worker         CheckedNumeric<size_t> checkedEndByte(endByte);
7497*8975f5c5SAndroid Build Coastguard Worker         CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
7498*8975f5c5SAndroid Build Coastguard Worker         checkedEndByte += checkedOffset;
7499*8975f5c5SAndroid Build Coastguard Worker 
7500*8975f5c5SAndroid Build Coastguard Worker         if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
7501*8975f5c5SAndroid Build Coastguard Worker         {
7502*8975f5c5SAndroid Build Coastguard Worker             // Overflow past the end of the buffer
7503*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kParamOverflow);
7504*8975f5c5SAndroid Build Coastguard Worker             return false;
7505*8975f5c5SAndroid Build Coastguard Worker         }
7506*8975f5c5SAndroid Build Coastguard Worker     }
7507*8975f5c5SAndroid Build Coastguard Worker 
7508*8975f5c5SAndroid Build Coastguard Worker     if (pixelPackBuffer == nullptr && length != nullptr)
7509*8975f5c5SAndroid Build Coastguard Worker     {
7510*8975f5c5SAndroid Build Coastguard Worker         if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
7511*8975f5c5SAndroid Build Coastguard Worker         {
7512*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7513*8975f5c5SAndroid Build Coastguard Worker             return false;
7514*8975f5c5SAndroid Build Coastguard Worker         }
7515*8975f5c5SAndroid Build Coastguard Worker 
7516*8975f5c5SAndroid Build Coastguard Worker         *length = static_cast<GLsizei>(endByte);
7517*8975f5c5SAndroid Build Coastguard Worker     }
7518*8975f5c5SAndroid Build Coastguard Worker 
7519*8975f5c5SAndroid Build Coastguard Worker     if (context->isWebGL())
7520*8975f5c5SAndroid Build Coastguard Worker     {
7521*8975f5c5SAndroid Build Coastguard Worker         // WebGL 2.0 disallows the scenario:
7522*8975f5c5SAndroid Build Coastguard Worker         //   GL_PACK_SKIP_PIXELS + width > DataStoreWidth
7523*8975f5c5SAndroid Build Coastguard Worker         // where:
7524*8975f5c5SAndroid Build Coastguard Worker         //   DataStoreWidth = (GL_PACK_ROW_LENGTH ? GL_PACK_ROW_LENGTH : width)
7525*8975f5c5SAndroid Build Coastguard Worker         // Since these two pack parameters can only be set to non-zero values
7526*8975f5c5SAndroid Build Coastguard Worker         // on WebGL 2.0 contexts, verify them for all WebGL contexts.
7527*8975f5c5SAndroid Build Coastguard Worker         GLint dataStoreWidth = pack.rowLength ? pack.rowLength : width;
7528*8975f5c5SAndroid Build Coastguard Worker         if (pack.skipPixels + width > dataStoreWidth)
7529*8975f5c5SAndroid Build Coastguard Worker         {
7530*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidPackParametersForWebGL);
7531*8975f5c5SAndroid Build Coastguard Worker             return false;
7532*8975f5c5SAndroid Build Coastguard Worker         }
7533*8975f5c5SAndroid Build Coastguard Worker     }
7534*8975f5c5SAndroid Build Coastguard Worker 
7535*8975f5c5SAndroid Build Coastguard Worker     return true;
7536*8975f5c5SAndroid Build Coastguard Worker }
7537*8975f5c5SAndroid Build Coastguard Worker 
ValidateReadPixelsBase(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLsizei * length,GLsizei * columns,GLsizei * rows,const void * pixels)7538*8975f5c5SAndroid Build Coastguard Worker bool ValidateReadPixelsBase(const Context *context,
7539*8975f5c5SAndroid Build Coastguard Worker                             angle::EntryPoint entryPoint,
7540*8975f5c5SAndroid Build Coastguard Worker                             GLint x,
7541*8975f5c5SAndroid Build Coastguard Worker                             GLint y,
7542*8975f5c5SAndroid Build Coastguard Worker                             GLsizei width,
7543*8975f5c5SAndroid Build Coastguard Worker                             GLsizei height,
7544*8975f5c5SAndroid Build Coastguard Worker                             GLenum format,
7545*8975f5c5SAndroid Build Coastguard Worker                             GLenum type,
7546*8975f5c5SAndroid Build Coastguard Worker                             GLsizei bufSize,
7547*8975f5c5SAndroid Build Coastguard Worker                             GLsizei *length,
7548*8975f5c5SAndroid Build Coastguard Worker                             GLsizei *columns,
7549*8975f5c5SAndroid Build Coastguard Worker                             GLsizei *rows,
7550*8975f5c5SAndroid Build Coastguard Worker                             const void *pixels)
7551*8975f5c5SAndroid Build Coastguard Worker {
7552*8975f5c5SAndroid Build Coastguard Worker     if (length != nullptr)
7553*8975f5c5SAndroid Build Coastguard Worker     {
7554*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
7555*8975f5c5SAndroid Build Coastguard Worker     }
7556*8975f5c5SAndroid Build Coastguard Worker     if (rows != nullptr)
7557*8975f5c5SAndroid Build Coastguard Worker     {
7558*8975f5c5SAndroid Build Coastguard Worker         *rows = 0;
7559*8975f5c5SAndroid Build Coastguard Worker     }
7560*8975f5c5SAndroid Build Coastguard Worker     if (columns != nullptr)
7561*8975f5c5SAndroid Build Coastguard Worker     {
7562*8975f5c5SAndroid Build Coastguard Worker         *columns = 0;
7563*8975f5c5SAndroid Build Coastguard Worker     }
7564*8975f5c5SAndroid Build Coastguard Worker 
7565*8975f5c5SAndroid Build Coastguard Worker     if (width < 0 || height < 0)
7566*8975f5c5SAndroid Build Coastguard Worker     {
7567*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
7568*8975f5c5SAndroid Build Coastguard Worker         return false;
7569*8975f5c5SAndroid Build Coastguard Worker     }
7570*8975f5c5SAndroid Build Coastguard Worker 
7571*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
7572*8975f5c5SAndroid Build Coastguard Worker     ASSERT(readFramebuffer);
7573*8975f5c5SAndroid Build Coastguard Worker 
7574*8975f5c5SAndroid Build Coastguard Worker     if (!ValidateFramebufferComplete(context, entryPoint, readFramebuffer))
7575*8975f5c5SAndroid Build Coastguard Worker     {
7576*8975f5c5SAndroid Build Coastguard Worker         return false;
7577*8975f5c5SAndroid Build Coastguard Worker     }
7578*8975f5c5SAndroid Build Coastguard Worker 
7579*8975f5c5SAndroid Build Coastguard Worker     // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be
7580*8975f5c5SAndroid Build Coastguard Worker     // resolved before reading.
7581*8975f5c5SAndroid Build Coastguard Worker     if (!readFramebuffer->isDefault() &&
7582*8975f5c5SAndroid Build Coastguard Worker         !ValidateFramebufferNotMultisampled(context, entryPoint, readFramebuffer, true))
7583*8975f5c5SAndroid Build Coastguard Worker     {
7584*8975f5c5SAndroid Build Coastguard Worker         return false;
7585*8975f5c5SAndroid Build Coastguard Worker     }
7586*8975f5c5SAndroid Build Coastguard Worker 
7587*8975f5c5SAndroid Build Coastguard Worker     if (readFramebuffer->getReadBufferState() == GL_NONE)
7588*8975f5c5SAndroid Build Coastguard Worker     {
7589*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kReadBufferNone);
7590*8975f5c5SAndroid Build Coastguard Worker         return false;
7591*8975f5c5SAndroid Build Coastguard Worker     }
7592*8975f5c5SAndroid Build Coastguard Worker 
7593*8975f5c5SAndroid Build Coastguard Worker     const FramebufferAttachment *readBuffer = nullptr;
7594*8975f5c5SAndroid Build Coastguard Worker     switch (format)
7595*8975f5c5SAndroid Build Coastguard Worker     {
7596*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_COMPONENT:
7597*8975f5c5SAndroid Build Coastguard Worker             readBuffer = readFramebuffer->getDepthAttachment();
7598*8975f5c5SAndroid Build Coastguard Worker             break;
7599*8975f5c5SAndroid Build Coastguard Worker         case GL_STENCIL_INDEX_OES:
7600*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_STENCIL_OES:
7601*8975f5c5SAndroid Build Coastguard Worker             readBuffer = readFramebuffer->getStencilOrDepthStencilAttachment();
7602*8975f5c5SAndroid Build Coastguard Worker             break;
7603*8975f5c5SAndroid Build Coastguard Worker         default:
7604*8975f5c5SAndroid Build Coastguard Worker             readBuffer = readFramebuffer->getReadColorAttachment();
7605*8975f5c5SAndroid Build Coastguard Worker             break;
7606*8975f5c5SAndroid Build Coastguard Worker     }
7607*8975f5c5SAndroid Build Coastguard Worker 
7608*8975f5c5SAndroid Build Coastguard Worker     // OVR_multiview2, Revision 1:
7609*8975f5c5SAndroid Build Coastguard Worker     // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if
7610*8975f5c5SAndroid Build Coastguard Worker     // the number of views in the current read framebuffer is more than one.
7611*8975f5c5SAndroid Build Coastguard Worker     if (readFramebuffer->readDisallowedByMultiview())
7612*8975f5c5SAndroid Build Coastguard Worker     {
7613*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
7614*8975f5c5SAndroid Build Coastguard Worker         return false;
7615*8975f5c5SAndroid Build Coastguard Worker     }
7616*8975f5c5SAndroid Build Coastguard Worker 
7617*8975f5c5SAndroid Build Coastguard Worker     if (context->isWebGL())
7618*8975f5c5SAndroid Build Coastguard Worker     {
7619*8975f5c5SAndroid Build Coastguard Worker         // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
7620*8975f5c5SAndroid Build Coastguard Worker         // excluding formats LUMINANCE and LUMINANCE_ALPHA.".  This requires validating the format
7621*8975f5c5SAndroid Build Coastguard Worker         // and type before validating the combination of format and type.  However, the
7622*8975f5c5SAndroid Build Coastguard Worker         // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
7623*8975f5c5SAndroid Build Coastguard Worker         // verifies that GL_INVALID_OPERATION is generated.
7624*8975f5c5SAndroid Build Coastguard Worker         // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
7625*8975f5c5SAndroid Build Coastguard Worker         // dEQP/WebGL.
7626*8975f5c5SAndroid Build Coastguard Worker         if (!ValidReadPixelsFormatEnum(context, format))
7627*8975f5c5SAndroid Build Coastguard Worker         {
7628*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
7629*8975f5c5SAndroid Build Coastguard Worker             return false;
7630*8975f5c5SAndroid Build Coastguard Worker         }
7631*8975f5c5SAndroid Build Coastguard Worker 
7632*8975f5c5SAndroid Build Coastguard Worker         if (!ValidReadPixelsTypeEnum(context, type))
7633*8975f5c5SAndroid Build Coastguard Worker         {
7634*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
7635*8975f5c5SAndroid Build Coastguard Worker             return false;
7636*8975f5c5SAndroid Build Coastguard Worker         }
7637*8975f5c5SAndroid Build Coastguard Worker     }
7638*8975f5c5SAndroid Build Coastguard Worker 
7639*8975f5c5SAndroid Build Coastguard Worker     // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
7640*8975f5c5SAndroid Build Coastguard Worker     // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
7641*8975f5c5SAndroid Build Coastguard Worker     // attachment and WebGL defines it to be an error. We do the check unconditionally as the
7642*8975f5c5SAndroid Build Coastguard Worker     // situation is an application error that would lead to a crash in ANGLE.
7643*8975f5c5SAndroid Build Coastguard Worker     if (readBuffer == nullptr)
7644*8975f5c5SAndroid Build Coastguard Worker     {
7645*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingReadAttachment);
7646*8975f5c5SAndroid Build Coastguard Worker         return false;
7647*8975f5c5SAndroid Build Coastguard Worker     }
7648*8975f5c5SAndroid Build Coastguard Worker 
7649*8975f5c5SAndroid Build Coastguard Worker     GLenum currentFormat = GL_NONE;
7650*8975f5c5SAndroid Build Coastguard Worker     GLenum currentType   = GL_NONE;
7651*8975f5c5SAndroid Build Coastguard Worker 
7652*8975f5c5SAndroid Build Coastguard Worker     switch (format)
7653*8975f5c5SAndroid Build Coastguard Worker     {
7654*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_COMPONENT:
7655*8975f5c5SAndroid Build Coastguard Worker         case GL_STENCIL_INDEX_OES:
7656*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_STENCIL_OES:
7657*8975f5c5SAndroid Build Coastguard Worker             // Only rely on ValidReadPixelsFormatType for depth/stencil formats
7658*8975f5c5SAndroid Build Coastguard Worker             break;
7659*8975f5c5SAndroid Build Coastguard Worker         default:
7660*8975f5c5SAndroid Build Coastguard Worker             currentFormat = readFramebuffer->getImplementationColorReadFormat(context);
7661*8975f5c5SAndroid Build Coastguard Worker             currentType   = readFramebuffer->getImplementationColorReadType(context);
7662*8975f5c5SAndroid Build Coastguard Worker             break;
7663*8975f5c5SAndroid Build Coastguard Worker     }
7664*8975f5c5SAndroid Build Coastguard Worker 
7665*8975f5c5SAndroid Build Coastguard Worker     bool validFormatTypeCombination =
7666*8975f5c5SAndroid Build Coastguard Worker         ValidReadPixelsFormatType(context, readBuffer->getFormat().info, format, type);
7667*8975f5c5SAndroid Build Coastguard Worker 
7668*8975f5c5SAndroid Build Coastguard Worker     if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
7669*8975f5c5SAndroid Build Coastguard Worker     {
7670*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
7671*8975f5c5SAndroid Build Coastguard Worker         return false;
7672*8975f5c5SAndroid Build Coastguard Worker     }
7673*8975f5c5SAndroid Build Coastguard Worker 
7674*8975f5c5SAndroid Build Coastguard Worker     if (!ValidatePixelPack(context, entryPoint, format, type, x, y, width, height, bufSize, length,
7675*8975f5c5SAndroid Build Coastguard Worker                            pixels))
7676*8975f5c5SAndroid Build Coastguard Worker     {
7677*8975f5c5SAndroid Build Coastguard Worker         return false;
7678*8975f5c5SAndroid Build Coastguard Worker     }
7679*8975f5c5SAndroid Build Coastguard Worker 
7680*8975f5c5SAndroid Build Coastguard Worker     auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
7681*8975f5c5SAndroid Build Coastguard Worker         angle::CheckedNumeric<int> clippedExtent(length);
7682*8975f5c5SAndroid Build Coastguard Worker         if (start < 0)
7683*8975f5c5SAndroid Build Coastguard Worker         {
7684*8975f5c5SAndroid Build Coastguard Worker             // "subtract" the area that is less than 0
7685*8975f5c5SAndroid Build Coastguard Worker             clippedExtent += start;
7686*8975f5c5SAndroid Build Coastguard Worker         }
7687*8975f5c5SAndroid Build Coastguard Worker 
7688*8975f5c5SAndroid Build Coastguard Worker         angle::CheckedNumeric<int> readExtent = start;
7689*8975f5c5SAndroid Build Coastguard Worker         readExtent += length;
7690*8975f5c5SAndroid Build Coastguard Worker         if (!readExtent.IsValid())
7691*8975f5c5SAndroid Build Coastguard Worker         {
7692*8975f5c5SAndroid Build Coastguard Worker             return false;
7693*8975f5c5SAndroid Build Coastguard Worker         }
7694*8975f5c5SAndroid Build Coastguard Worker 
7695*8975f5c5SAndroid Build Coastguard Worker         if (readExtent.ValueOrDie() > bufferSize)
7696*8975f5c5SAndroid Build Coastguard Worker         {
7697*8975f5c5SAndroid Build Coastguard Worker             // Subtract the region to the right of the read buffer
7698*8975f5c5SAndroid Build Coastguard Worker             clippedExtent -= (readExtent - bufferSize);
7699*8975f5c5SAndroid Build Coastguard Worker         }
7700*8975f5c5SAndroid Build Coastguard Worker 
7701*8975f5c5SAndroid Build Coastguard Worker         if (!clippedExtent.IsValid())
7702*8975f5c5SAndroid Build Coastguard Worker         {
7703*8975f5c5SAndroid Build Coastguard Worker             return false;
7704*8975f5c5SAndroid Build Coastguard Worker         }
7705*8975f5c5SAndroid Build Coastguard Worker 
7706*8975f5c5SAndroid Build Coastguard Worker         *outExtent = std::max<int>(clippedExtent.ValueOrDie(), 0);
7707*8975f5c5SAndroid Build Coastguard Worker         return true;
7708*8975f5c5SAndroid Build Coastguard Worker     };
7709*8975f5c5SAndroid Build Coastguard Worker 
7710*8975f5c5SAndroid Build Coastguard Worker     GLsizei writtenColumns = 0;
7711*8975f5c5SAndroid Build Coastguard Worker     if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
7712*8975f5c5SAndroid Build Coastguard Worker     {
7713*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7714*8975f5c5SAndroid Build Coastguard Worker         return false;
7715*8975f5c5SAndroid Build Coastguard Worker     }
7716*8975f5c5SAndroid Build Coastguard Worker 
7717*8975f5c5SAndroid Build Coastguard Worker     GLsizei writtenRows = 0;
7718*8975f5c5SAndroid Build Coastguard Worker     if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
7719*8975f5c5SAndroid Build Coastguard Worker     {
7720*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
7721*8975f5c5SAndroid Build Coastguard Worker         return false;
7722*8975f5c5SAndroid Build Coastguard Worker     }
7723*8975f5c5SAndroid Build Coastguard Worker 
7724*8975f5c5SAndroid Build Coastguard Worker     if (columns != nullptr)
7725*8975f5c5SAndroid Build Coastguard Worker     {
7726*8975f5c5SAndroid Build Coastguard Worker         *columns = writtenColumns;
7727*8975f5c5SAndroid Build Coastguard Worker     }
7728*8975f5c5SAndroid Build Coastguard Worker 
7729*8975f5c5SAndroid Build Coastguard Worker     if (rows != nullptr)
7730*8975f5c5SAndroid Build Coastguard Worker     {
7731*8975f5c5SAndroid Build Coastguard Worker         *rows = writtenRows;
7732*8975f5c5SAndroid Build Coastguard Worker     }
7733*8975f5c5SAndroid Build Coastguard Worker 
7734*8975f5c5SAndroid Build Coastguard Worker     return true;
7735*8975f5c5SAndroid Build Coastguard Worker }
7736*8975f5c5SAndroid Build Coastguard Worker 
7737*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateTexParameterBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLsizei bufSize,bool vectorParams,const ParamType * params)7738*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexParameterBase(const Context *context,
7739*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
7740*8975f5c5SAndroid Build Coastguard Worker                               TextureType target,
7741*8975f5c5SAndroid Build Coastguard Worker                               GLenum pname,
7742*8975f5c5SAndroid Build Coastguard Worker                               GLsizei bufSize,
7743*8975f5c5SAndroid Build Coastguard Worker                               bool vectorParams,
7744*8975f5c5SAndroid Build Coastguard Worker                               const ParamType *params)
7745*8975f5c5SAndroid Build Coastguard Worker {
7746*8975f5c5SAndroid Build Coastguard Worker     if ((!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target)) ||
7747*8975f5c5SAndroid Build Coastguard Worker         target == TextureType::Buffer)
7748*8975f5c5SAndroid Build Coastguard Worker     {
7749*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
7750*8975f5c5SAndroid Build Coastguard Worker         return false;
7751*8975f5c5SAndroid Build Coastguard Worker     }
7752*8975f5c5SAndroid Build Coastguard Worker 
7753*8975f5c5SAndroid Build Coastguard Worker     if (context->getTextureByType(target) == nullptr)
7754*8975f5c5SAndroid Build Coastguard Worker     {
7755*8975f5c5SAndroid Build Coastguard Worker         // Should only be possible for external textures
7756*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureNotBound);
7757*8975f5c5SAndroid Build Coastguard Worker         return false;
7758*8975f5c5SAndroid Build Coastguard Worker     }
7759*8975f5c5SAndroid Build Coastguard Worker 
7760*8975f5c5SAndroid Build Coastguard Worker     const GLsizei minBufSize = GetTexParameterCount(pname);
7761*8975f5c5SAndroid Build Coastguard Worker     if (bufSize >= 0 && bufSize < minBufSize)
7762*8975f5c5SAndroid Build Coastguard Worker     {
7763*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
7764*8975f5c5SAndroid Build Coastguard Worker         return false;
7765*8975f5c5SAndroid Build Coastguard Worker     }
7766*8975f5c5SAndroid Build Coastguard Worker 
7767*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
7768*8975f5c5SAndroid Build Coastguard Worker     {
7769*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7770*8975f5c5SAndroid Build Coastguard Worker         return false;
7771*8975f5c5SAndroid Build Coastguard Worker     }
7772*8975f5c5SAndroid Build Coastguard Worker 
7773*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
7774*8975f5c5SAndroid Build Coastguard Worker     {
7775*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_R:
7776*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_R:
7777*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_G:
7778*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_B:
7779*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_A:
7780*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BASE_LEVEL:
7781*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LEVEL:
7782*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_MODE:
7783*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_FUNC:
7784*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_LOD:
7785*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LOD:
7786*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() < 3 &&
7787*8975f5c5SAndroid Build Coastguard Worker                 !(pname == GL_TEXTURE_WRAP_R && context->getExtensions().texture3DOES))
7788*8975f5c5SAndroid Build Coastguard Worker             {
7789*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES3Required);
7790*8975f5c5SAndroid Build Coastguard Worker                 return false;
7791*8975f5c5SAndroid Build Coastguard Worker             }
7792*8975f5c5SAndroid Build Coastguard Worker             if (target == TextureType::VideoImage && !context->getExtensions().videoTextureWEBGL)
7793*8975f5c5SAndroid Build Coastguard Worker             {
7794*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7795*8975f5c5SAndroid Build Coastguard Worker             }
7796*8975f5c5SAndroid Build Coastguard Worker             break;
7797*8975f5c5SAndroid Build Coastguard Worker 
7798*8975f5c5SAndroid Build Coastguard Worker         case GL_GENERATE_MIPMAP:
7799*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CROP_RECT_OES:
7800*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() > 1)
7801*8975f5c5SAndroid Build Coastguard Worker             {
7802*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
7803*8975f5c5SAndroid Build Coastguard Worker                 return false;
7804*8975f5c5SAndroid Build Coastguard Worker             }
7805*8975f5c5SAndroid Build Coastguard Worker             break;
7806*8975f5c5SAndroid Build Coastguard Worker 
7807*8975f5c5SAndroid Build Coastguard Worker         default:
7808*8975f5c5SAndroid Build Coastguard Worker             break;
7809*8975f5c5SAndroid Build Coastguard Worker     }
7810*8975f5c5SAndroid Build Coastguard Worker 
7811*8975f5c5SAndroid Build Coastguard Worker     if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
7812*8975f5c5SAndroid Build Coastguard Worker     {
7813*8975f5c5SAndroid Build Coastguard Worker         switch (pname)
7814*8975f5c5SAndroid Build Coastguard Worker         {
7815*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_MIN_FILTER:
7816*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_MAG_FILTER:
7817*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_WRAP_S:
7818*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_WRAP_T:
7819*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_WRAP_R:
7820*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_MIN_LOD:
7821*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_MAX_LOD:
7822*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_COMPARE_MODE:
7823*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_COMPARE_FUNC:
7824*8975f5c5SAndroid Build Coastguard Worker             case GL_TEXTURE_BORDER_COLOR:
7825*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
7826*8975f5c5SAndroid Build Coastguard Worker                 return false;
7827*8975f5c5SAndroid Build Coastguard Worker         }
7828*8975f5c5SAndroid Build Coastguard Worker     }
7829*8975f5c5SAndroid Build Coastguard Worker 
7830*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
7831*8975f5c5SAndroid Build Coastguard Worker     {
7832*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_S:
7833*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_T:
7834*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_R:
7835*8975f5c5SAndroid Build Coastguard Worker         {
7836*8975f5c5SAndroid Build Coastguard Worker             bool restrictedWrapModes = ((target == TextureType::External &&
7837*8975f5c5SAndroid Build Coastguard Worker                                          !context->getExtensions().EGLImageExternalWrapModesEXT) ||
7838*8975f5c5SAndroid Build Coastguard Worker                                         target == TextureType::Rectangle);
7839*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureWrapModeValue(context, entryPoint, params, restrictedWrapModes))
7840*8975f5c5SAndroid Build Coastguard Worker             {
7841*8975f5c5SAndroid Build Coastguard Worker                 return false;
7842*8975f5c5SAndroid Build Coastguard Worker             }
7843*8975f5c5SAndroid Build Coastguard Worker         }
7844*8975f5c5SAndroid Build Coastguard Worker         break;
7845*8975f5c5SAndroid Build Coastguard Worker 
7846*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_FILTER:
7847*8975f5c5SAndroid Build Coastguard Worker         {
7848*8975f5c5SAndroid Build Coastguard Worker             bool restrictedMinFilter =
7849*8975f5c5SAndroid Build Coastguard Worker                 target == TextureType::External || target == TextureType::Rectangle;
7850*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMinFilterValue(context, entryPoint, params, restrictedMinFilter))
7851*8975f5c5SAndroid Build Coastguard Worker             {
7852*8975f5c5SAndroid Build Coastguard Worker                 return false;
7853*8975f5c5SAndroid Build Coastguard Worker             }
7854*8975f5c5SAndroid Build Coastguard Worker         }
7855*8975f5c5SAndroid Build Coastguard Worker         break;
7856*8975f5c5SAndroid Build Coastguard Worker 
7857*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAG_FILTER:
7858*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMagFilterValue(context, entryPoint, params))
7859*8975f5c5SAndroid Build Coastguard Worker             {
7860*8975f5c5SAndroid Build Coastguard Worker                 return false;
7861*8975f5c5SAndroid Build Coastguard Worker             }
7862*8975f5c5SAndroid Build Coastguard Worker             break;
7863*8975f5c5SAndroid Build Coastguard Worker 
7864*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_USAGE_ANGLE:
7865*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureUsageANGLE)
7866*8975f5c5SAndroid Build Coastguard Worker             {
7867*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7868*8975f5c5SAndroid Build Coastguard Worker                 return false;
7869*8975f5c5SAndroid Build Coastguard Worker             }
7870*8975f5c5SAndroid Build Coastguard Worker 
7871*8975f5c5SAndroid Build Coastguard Worker             switch (ConvertToGLenum(params[0]))
7872*8975f5c5SAndroid Build Coastguard Worker             {
7873*8975f5c5SAndroid Build Coastguard Worker                 case GL_NONE:
7874*8975f5c5SAndroid Build Coastguard Worker                 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
7875*8975f5c5SAndroid Build Coastguard Worker                     break;
7876*8975f5c5SAndroid Build Coastguard Worker 
7877*8975f5c5SAndroid Build Coastguard Worker                 default:
7878*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7879*8975f5c5SAndroid Build Coastguard Worker                     return false;
7880*8975f5c5SAndroid Build Coastguard Worker             }
7881*8975f5c5SAndroid Build Coastguard Worker             break;
7882*8975f5c5SAndroid Build Coastguard Worker 
7883*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
7884*8975f5c5SAndroid Build Coastguard Worker         {
7885*8975f5c5SAndroid Build Coastguard Worker             GLfloat paramValue = static_cast<GLfloat>(params[0]);
7886*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue))
7887*8975f5c5SAndroid Build Coastguard Worker             {
7888*8975f5c5SAndroid Build Coastguard Worker                 return false;
7889*8975f5c5SAndroid Build Coastguard Worker             }
7890*8975f5c5SAndroid Build Coastguard Worker             ASSERT(static_cast<ParamType>(paramValue) == params[0]);
7891*8975f5c5SAndroid Build Coastguard Worker         }
7892*8975f5c5SAndroid Build Coastguard Worker         break;
7893*8975f5c5SAndroid Build Coastguard Worker 
7894*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_LOD:
7895*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LOD:
7896*8975f5c5SAndroid Build Coastguard Worker             // any value is permissible
7897*8975f5c5SAndroid Build Coastguard Worker             break;
7898*8975f5c5SAndroid Build Coastguard Worker 
7899*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_MODE:
7900*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureCompareModeValue(context, entryPoint, params))
7901*8975f5c5SAndroid Build Coastguard Worker             {
7902*8975f5c5SAndroid Build Coastguard Worker                 return false;
7903*8975f5c5SAndroid Build Coastguard Worker             }
7904*8975f5c5SAndroid Build Coastguard Worker             break;
7905*8975f5c5SAndroid Build Coastguard Worker 
7906*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_FUNC:
7907*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureCompareFuncValue(context, entryPoint, params))
7908*8975f5c5SAndroid Build Coastguard Worker             {
7909*8975f5c5SAndroid Build Coastguard Worker                 return false;
7910*8975f5c5SAndroid Build Coastguard Worker             }
7911*8975f5c5SAndroid Build Coastguard Worker             break;
7912*8975f5c5SAndroid Build Coastguard Worker 
7913*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_R:
7914*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_G:
7915*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_B:
7916*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SWIZZLE_A:
7917*8975f5c5SAndroid Build Coastguard Worker             switch (ConvertToGLenum(params[0]))
7918*8975f5c5SAndroid Build Coastguard Worker             {
7919*8975f5c5SAndroid Build Coastguard Worker                 case GL_RED:
7920*8975f5c5SAndroid Build Coastguard Worker                 case GL_GREEN:
7921*8975f5c5SAndroid Build Coastguard Worker                 case GL_BLUE:
7922*8975f5c5SAndroid Build Coastguard Worker                 case GL_ALPHA:
7923*8975f5c5SAndroid Build Coastguard Worker                 case GL_ZERO:
7924*8975f5c5SAndroid Build Coastguard Worker                 case GL_ONE:
7925*8975f5c5SAndroid Build Coastguard Worker                     break;
7926*8975f5c5SAndroid Build Coastguard Worker 
7927*8975f5c5SAndroid Build Coastguard Worker                 default:
7928*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7929*8975f5c5SAndroid Build Coastguard Worker                     return false;
7930*8975f5c5SAndroid Build Coastguard Worker             }
7931*8975f5c5SAndroid Build Coastguard Worker             break;
7932*8975f5c5SAndroid Build Coastguard Worker 
7933*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BASE_LEVEL:
7934*8975f5c5SAndroid Build Coastguard Worker             if (ConvertToGLint(params[0]) < 0)
7935*8975f5c5SAndroid Build Coastguard Worker             {
7936*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBaseLevelNegative);
7937*8975f5c5SAndroid Build Coastguard Worker                 return false;
7938*8975f5c5SAndroid Build Coastguard Worker             }
7939*8975f5c5SAndroid Build Coastguard Worker             if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
7940*8975f5c5SAndroid Build Coastguard Worker             {
7941*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelNonZero);
7942*8975f5c5SAndroid Build Coastguard Worker                 return false;
7943*8975f5c5SAndroid Build Coastguard Worker             }
7944*8975f5c5SAndroid Build Coastguard Worker             if ((target == TextureType::_2DMultisample ||
7945*8975f5c5SAndroid Build Coastguard Worker                  target == TextureType::_2DMultisampleArray) &&
7946*8975f5c5SAndroid Build Coastguard Worker                 static_cast<GLuint>(params[0]) != 0)
7947*8975f5c5SAndroid Build Coastguard Worker             {
7948*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelNonZero);
7949*8975f5c5SAndroid Build Coastguard Worker                 return false;
7950*8975f5c5SAndroid Build Coastguard Worker             }
7951*8975f5c5SAndroid Build Coastguard Worker             if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
7952*8975f5c5SAndroid Build Coastguard Worker             {
7953*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBaseLevelNonZero);
7954*8975f5c5SAndroid Build Coastguard Worker                 return false;
7955*8975f5c5SAndroid Build Coastguard Worker             }
7956*8975f5c5SAndroid Build Coastguard Worker             break;
7957*8975f5c5SAndroid Build Coastguard Worker 
7958*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LEVEL:
7959*8975f5c5SAndroid Build Coastguard Worker             if (ConvertToGLint(params[0]) < 0)
7960*8975f5c5SAndroid Build Coastguard Worker             {
7961*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
7962*8975f5c5SAndroid Build Coastguard Worker                 return false;
7963*8975f5c5SAndroid Build Coastguard Worker             }
7964*8975f5c5SAndroid Build Coastguard Worker             break;
7965*8975f5c5SAndroid Build Coastguard Worker 
7966*8975f5c5SAndroid Build Coastguard Worker         case GL_DEPTH_STENCIL_TEXTURE_MODE:
7967*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_1 &&
7968*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().stencilTexturingANGLE)
7969*8975f5c5SAndroid Build Coastguard Worker             {
7970*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7971*8975f5c5SAndroid Build Coastguard Worker                 return false;
7972*8975f5c5SAndroid Build Coastguard Worker             }
7973*8975f5c5SAndroid Build Coastguard Worker             switch (ConvertToGLenum(params[0]))
7974*8975f5c5SAndroid Build Coastguard Worker             {
7975*8975f5c5SAndroid Build Coastguard Worker                 case GL_DEPTH_COMPONENT:
7976*8975f5c5SAndroid Build Coastguard Worker                 case GL_STENCIL_INDEX:
7977*8975f5c5SAndroid Build Coastguard Worker                     break;
7978*8975f5c5SAndroid Build Coastguard Worker 
7979*8975f5c5SAndroid Build Coastguard Worker                 default:
7980*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
7981*8975f5c5SAndroid Build Coastguard Worker                     return false;
7982*8975f5c5SAndroid Build Coastguard Worker             }
7983*8975f5c5SAndroid Build Coastguard Worker             break;
7984*8975f5c5SAndroid Build Coastguard Worker 
7985*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SRGB_DECODE_EXT:
7986*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params))
7987*8975f5c5SAndroid Build Coastguard Worker             {
7988*8975f5c5SAndroid Build Coastguard Worker                 return false;
7989*8975f5c5SAndroid Build Coastguard Worker             }
7990*8975f5c5SAndroid Build Coastguard Worker             break;
7991*8975f5c5SAndroid Build Coastguard Worker 
7992*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
7993*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureSRGBOverrideValue(context, entryPoint, params))
7994*8975f5c5SAndroid Build Coastguard Worker             {
7995*8975f5c5SAndroid Build Coastguard Worker                 return false;
7996*8975f5c5SAndroid Build Coastguard Worker             }
7997*8975f5c5SAndroid Build Coastguard Worker             break;
7998*8975f5c5SAndroid Build Coastguard Worker 
7999*8975f5c5SAndroid Build Coastguard Worker         case GL_GENERATE_MIPMAP:
8000*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() > 1)
8001*8975f5c5SAndroid Build Coastguard Worker             {
8002*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
8003*8975f5c5SAndroid Build Coastguard Worker                 return false;
8004*8975f5c5SAndroid Build Coastguard Worker             }
8005*8975f5c5SAndroid Build Coastguard Worker             break;
8006*8975f5c5SAndroid Build Coastguard Worker 
8007*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CROP_RECT_OES:
8008*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientMajorVersion() > 1)
8009*8975f5c5SAndroid Build Coastguard Worker             {
8010*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kGLES1Only);
8011*8975f5c5SAndroid Build Coastguard Worker                 return false;
8012*8975f5c5SAndroid Build Coastguard Worker             }
8013*8975f5c5SAndroid Build Coastguard Worker             if (!vectorParams)
8014*8975f5c5SAndroid Build Coastguard Worker             {
8015*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
8016*8975f5c5SAndroid Build Coastguard Worker                 return false;
8017*8975f5c5SAndroid Build Coastguard Worker             }
8018*8975f5c5SAndroid Build Coastguard Worker             break;
8019*8975f5c5SAndroid Build Coastguard Worker 
8020*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BORDER_COLOR:
8021*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureBorderClampAny() &&
8022*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
8023*8975f5c5SAndroid Build Coastguard Worker             {
8024*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
8025*8975f5c5SAndroid Build Coastguard Worker                 return false;
8026*8975f5c5SAndroid Build Coastguard Worker             }
8027*8975f5c5SAndroid Build Coastguard Worker             if (!vectorParams)
8028*8975f5c5SAndroid Build Coastguard Worker             {
8029*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInsufficientBufferSize);
8030*8975f5c5SAndroid Build Coastguard Worker                 return false;
8031*8975f5c5SAndroid Build Coastguard Worker             }
8032*8975f5c5SAndroid Build Coastguard Worker             break;
8033*8975f5c5SAndroid Build Coastguard Worker 
8034*8975f5c5SAndroid Build Coastguard Worker         case GL_RESOURCE_INITIALIZED_ANGLE:
8035*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().robustResourceInitializationANGLE)
8036*8975f5c5SAndroid Build Coastguard Worker             {
8037*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8038*8975f5c5SAndroid Build Coastguard Worker                                        kRobustResourceInitializationExtensionRequired);
8039*8975f5c5SAndroid Build Coastguard Worker                 return false;
8040*8975f5c5SAndroid Build Coastguard Worker             }
8041*8975f5c5SAndroid Build Coastguard Worker             break;
8042*8975f5c5SAndroid Build Coastguard Worker 
8043*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_PROTECTED_EXT:
8044*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().protectedTexturesEXT)
8045*8975f5c5SAndroid Build Coastguard Worker             {
8046*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProtectedTexturesExtensionRequired);
8047*8975f5c5SAndroid Build Coastguard Worker                 return false;
8048*8975f5c5SAndroid Build Coastguard Worker             }
8049*8975f5c5SAndroid Build Coastguard Worker             if (ConvertToBool(params[0]) != context->getState().hasProtectedContent())
8050*8975f5c5SAndroid Build Coastguard Worker             {
8051*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
8052*8975f5c5SAndroid Build Coastguard Worker                                        "Protected Texture must match Protected Context");
8053*8975f5c5SAndroid Build Coastguard Worker                 return false;
8054*8975f5c5SAndroid Build Coastguard Worker             }
8055*8975f5c5SAndroid Build Coastguard Worker             break;
8056*8975f5c5SAndroid Build Coastguard Worker 
8057*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERABILITY_VALIDATION_ANGLE:
8058*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().renderabilityValidationANGLE)
8059*8975f5c5SAndroid Build Coastguard Worker             {
8060*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8061*8975f5c5SAndroid Build Coastguard Worker                 return false;
8062*8975f5c5SAndroid Build Coastguard Worker             }
8063*8975f5c5SAndroid Build Coastguard Worker             break;
8064*8975f5c5SAndroid Build Coastguard Worker 
8065*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_TILING_EXT:
8066*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().memoryObjectEXT)
8067*8975f5c5SAndroid Build Coastguard Worker             {
8068*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
8069*8975f5c5SAndroid Build Coastguard Worker                 return false;
8070*8975f5c5SAndroid Build Coastguard Worker             }
8071*8975f5c5SAndroid Build Coastguard Worker             switch (ConvertToGLenum(params[0]))
8072*8975f5c5SAndroid Build Coastguard Worker             {
8073*8975f5c5SAndroid Build Coastguard Worker                 case GL_OPTIMAL_TILING_EXT:
8074*8975f5c5SAndroid Build Coastguard Worker                 case GL_LINEAR_TILING_EXT:
8075*8975f5c5SAndroid Build Coastguard Worker                     break;
8076*8975f5c5SAndroid Build Coastguard Worker 
8077*8975f5c5SAndroid Build Coastguard Worker                 default:
8078*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(
8079*8975f5c5SAndroid Build Coastguard Worker                         GL_INVALID_OPERATION,
8080*8975f5c5SAndroid Build Coastguard Worker                         "Texture Tilling Mode must be OPTIMAL_TILING_EXT or LINEAR_TILING_EXT");
8081*8975f5c5SAndroid Build Coastguard Worker                     return false;
8082*8975f5c5SAndroid Build Coastguard Worker             }
8083*8975f5c5SAndroid Build Coastguard Worker             break;
8084*8975f5c5SAndroid Build Coastguard Worker 
8085*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM:
8086*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureFoveatedQCOM)
8087*8975f5c5SAndroid Build Coastguard Worker             {
8088*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
8089*8975f5c5SAndroid Build Coastguard Worker                 return false;
8090*8975f5c5SAndroid Build Coastguard Worker             }
8091*8975f5c5SAndroid Build Coastguard Worker             {
8092*8975f5c5SAndroid Build Coastguard Worker                 const GLuint features               = static_cast<GLuint>(params[0]);
8093*8975f5c5SAndroid Build Coastguard Worker                 constexpr GLuint kSupportedFeatures = GL_FOVEATION_ENABLE_BIT_QCOM;
8094*8975f5c5SAndroid Build Coastguard Worker                 if (features != (features & kSupportedFeatures))
8095*8975f5c5SAndroid Build Coastguard Worker                 {
8096*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureInvalidParameters);
8097*8975f5c5SAndroid Build Coastguard Worker                     return false;
8098*8975f5c5SAndroid Build Coastguard Worker                 }
8099*8975f5c5SAndroid Build Coastguard Worker                 if ((context->getTextureByType(target)->getFoveatedFeatureBits() &
8100*8975f5c5SAndroid Build Coastguard Worker                      GL_FOVEATION_ENABLE_BIT_QCOM) &&
8101*8975f5c5SAndroid Build Coastguard Worker                     (features & GL_FOVEATION_ENABLE_BIT_QCOM) == 0)
8102*8975f5c5SAndroid Build Coastguard Worker                 {
8103*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFoveatedTextureCannotDisable);
8104*8975f5c5SAndroid Build Coastguard Worker                     return false;
8105*8975f5c5SAndroid Build Coastguard Worker                 }
8106*8975f5c5SAndroid Build Coastguard Worker             }
8107*8975f5c5SAndroid Build Coastguard Worker             break;
8108*8975f5c5SAndroid Build Coastguard Worker 
8109*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM:
8110*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureFoveatedQCOM)
8111*8975f5c5SAndroid Build Coastguard Worker             {
8112*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFoveatedTextureQcomExtensionRequired);
8113*8975f5c5SAndroid Build Coastguard Worker                 return false;
8114*8975f5c5SAndroid Build Coastguard Worker             }
8115*8975f5c5SAndroid Build Coastguard Worker             if (static_cast<GLfloat>(params[0]) < 0.0 || static_cast<GLfloat>(params[0]) > 1.0)
8116*8975f5c5SAndroid Build Coastguard Worker             {
8117*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFoveatedTextureInvalidPixelDensity);
8118*8975f5c5SAndroid Build Coastguard Worker                 return false;
8119*8975f5c5SAndroid Build Coastguard Worker             }
8120*8975f5c5SAndroid Build Coastguard Worker             break;
8121*8975f5c5SAndroid Build Coastguard Worker 
8122*8975f5c5SAndroid Build Coastguard Worker         default:
8123*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8124*8975f5c5SAndroid Build Coastguard Worker             return false;
8125*8975f5c5SAndroid Build Coastguard Worker     }
8126*8975f5c5SAndroid Build Coastguard Worker 
8127*8975f5c5SAndroid Build Coastguard Worker     return true;
8128*8975f5c5SAndroid Build Coastguard Worker }
8129*8975f5c5SAndroid Build Coastguard Worker 
8130*8975f5c5SAndroid Build Coastguard Worker template bool ValidateTexParameterBase(const Context *,
8131*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint,
8132*8975f5c5SAndroid Build Coastguard Worker                                        TextureType,
8133*8975f5c5SAndroid Build Coastguard Worker                                        GLenum,
8134*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei,
8135*8975f5c5SAndroid Build Coastguard Worker                                        bool,
8136*8975f5c5SAndroid Build Coastguard Worker                                        const GLfloat *);
8137*8975f5c5SAndroid Build Coastguard Worker template bool ValidateTexParameterBase(const Context *,
8138*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint,
8139*8975f5c5SAndroid Build Coastguard Worker                                        TextureType,
8140*8975f5c5SAndroid Build Coastguard Worker                                        GLenum,
8141*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei,
8142*8975f5c5SAndroid Build Coastguard Worker                                        bool,
8143*8975f5c5SAndroid Build Coastguard Worker                                        const GLint *);
8144*8975f5c5SAndroid Build Coastguard Worker template bool ValidateTexParameterBase(const Context *,
8145*8975f5c5SAndroid Build Coastguard Worker                                        angle::EntryPoint,
8146*8975f5c5SAndroid Build Coastguard Worker                                        TextureType,
8147*8975f5c5SAndroid Build Coastguard Worker                                        GLenum,
8148*8975f5c5SAndroid Build Coastguard Worker                                        GLsizei,
8149*8975f5c5SAndroid Build Coastguard Worker                                        bool,
8150*8975f5c5SAndroid Build Coastguard Worker                                        const GLuint *);
8151*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetActiveUniformBlockivBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLsizei * length)8152*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetActiveUniformBlockivBase(const Context *context,
8153*8975f5c5SAndroid Build Coastguard Worker                                          angle::EntryPoint entryPoint,
8154*8975f5c5SAndroid Build Coastguard Worker                                          ShaderProgramID program,
8155*8975f5c5SAndroid Build Coastguard Worker                                          UniformBlockIndex uniformBlockIndex,
8156*8975f5c5SAndroid Build Coastguard Worker                                          GLenum pname,
8157*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei *length)
8158*8975f5c5SAndroid Build Coastguard Worker {
8159*8975f5c5SAndroid Build Coastguard Worker     if (length)
8160*8975f5c5SAndroid Build Coastguard Worker     {
8161*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
8162*8975f5c5SAndroid Build Coastguard Worker     }
8163*8975f5c5SAndroid Build Coastguard Worker 
8164*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() < 3)
8165*8975f5c5SAndroid Build Coastguard Worker     {
8166*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8167*8975f5c5SAndroid Build Coastguard Worker         return false;
8168*8975f5c5SAndroid Build Coastguard Worker     }
8169*8975f5c5SAndroid Build Coastguard Worker 
8170*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = GetValidProgram(context, entryPoint, program);
8171*8975f5c5SAndroid Build Coastguard Worker     if (!programObject)
8172*8975f5c5SAndroid Build Coastguard Worker     {
8173*8975f5c5SAndroid Build Coastguard Worker         return false;
8174*8975f5c5SAndroid Build Coastguard Worker     }
8175*8975f5c5SAndroid Build Coastguard Worker 
8176*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutable &executable = programObject->getExecutable();
8177*8975f5c5SAndroid Build Coastguard Worker     if (uniformBlockIndex.value >= executable.getUniformBlocks().size())
8178*8975f5c5SAndroid Build Coastguard Worker     {
8179*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsActiveUniformBlockCount);
8180*8975f5c5SAndroid Build Coastguard Worker         return false;
8181*8975f5c5SAndroid Build Coastguard Worker     }
8182*8975f5c5SAndroid Build Coastguard Worker 
8183*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
8184*8975f5c5SAndroid Build Coastguard Worker     {
8185*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_BINDING:
8186*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_DATA_SIZE:
8187*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_NAME_LENGTH:
8188*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
8189*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
8190*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
8191*8975f5c5SAndroid Build Coastguard Worker         case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
8192*8975f5c5SAndroid Build Coastguard Worker             break;
8193*8975f5c5SAndroid Build Coastguard Worker 
8194*8975f5c5SAndroid Build Coastguard Worker         default:
8195*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8196*8975f5c5SAndroid Build Coastguard Worker             return false;
8197*8975f5c5SAndroid Build Coastguard Worker     }
8198*8975f5c5SAndroid Build Coastguard Worker 
8199*8975f5c5SAndroid Build Coastguard Worker     if (length)
8200*8975f5c5SAndroid Build Coastguard Worker     {
8201*8975f5c5SAndroid Build Coastguard Worker         if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
8202*8975f5c5SAndroid Build Coastguard Worker         {
8203*8975f5c5SAndroid Build Coastguard Worker             const InterfaceBlock &uniformBlock =
8204*8975f5c5SAndroid Build Coastguard Worker                 executable.getUniformBlockByIndex(uniformBlockIndex.value);
8205*8975f5c5SAndroid Build Coastguard Worker             *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
8206*8975f5c5SAndroid Build Coastguard Worker         }
8207*8975f5c5SAndroid Build Coastguard Worker         else
8208*8975f5c5SAndroid Build Coastguard Worker         {
8209*8975f5c5SAndroid Build Coastguard Worker             *length = 1;
8210*8975f5c5SAndroid Build Coastguard Worker         }
8211*8975f5c5SAndroid Build Coastguard Worker     }
8212*8975f5c5SAndroid Build Coastguard Worker 
8213*8975f5c5SAndroid Build Coastguard Worker     return true;
8214*8975f5c5SAndroid Build Coastguard Worker }
8215*8975f5c5SAndroid Build Coastguard Worker 
8216*8975f5c5SAndroid Build Coastguard Worker template <typename ParamType>
ValidateSamplerParameterBase(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei bufSize,bool vectorParams,const ParamType * params)8217*8975f5c5SAndroid Build Coastguard Worker bool ValidateSamplerParameterBase(const Context *context,
8218*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
8219*8975f5c5SAndroid Build Coastguard Worker                                   SamplerID sampler,
8220*8975f5c5SAndroid Build Coastguard Worker                                   GLenum pname,
8221*8975f5c5SAndroid Build Coastguard Worker                                   GLsizei bufSize,
8222*8975f5c5SAndroid Build Coastguard Worker                                   bool vectorParams,
8223*8975f5c5SAndroid Build Coastguard Worker                                   const ParamType *params)
8224*8975f5c5SAndroid Build Coastguard Worker {
8225*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() < 3)
8226*8975f5c5SAndroid Build Coastguard Worker     {
8227*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8228*8975f5c5SAndroid Build Coastguard Worker         return false;
8229*8975f5c5SAndroid Build Coastguard Worker     }
8230*8975f5c5SAndroid Build Coastguard Worker 
8231*8975f5c5SAndroid Build Coastguard Worker     if (!context->isSampler(sampler))
8232*8975f5c5SAndroid Build Coastguard Worker     {
8233*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSampler);
8234*8975f5c5SAndroid Build Coastguard Worker         return false;
8235*8975f5c5SAndroid Build Coastguard Worker     }
8236*8975f5c5SAndroid Build Coastguard Worker 
8237*8975f5c5SAndroid Build Coastguard Worker     const GLsizei minBufSize = GetSamplerParameterCount(pname);
8238*8975f5c5SAndroid Build Coastguard Worker     if (bufSize >= 0 && bufSize < minBufSize)
8239*8975f5c5SAndroid Build Coastguard Worker     {
8240*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientBufferSize);
8241*8975f5c5SAndroid Build Coastguard Worker         return false;
8242*8975f5c5SAndroid Build Coastguard Worker     }
8243*8975f5c5SAndroid Build Coastguard Worker 
8244*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
8245*8975f5c5SAndroid Build Coastguard Worker     {
8246*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_S:
8247*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_T:
8248*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_R:
8249*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureWrapModeValue(context, entryPoint, params, false))
8250*8975f5c5SAndroid Build Coastguard Worker             {
8251*8975f5c5SAndroid Build Coastguard Worker                 return false;
8252*8975f5c5SAndroid Build Coastguard Worker             }
8253*8975f5c5SAndroid Build Coastguard Worker             break;
8254*8975f5c5SAndroid Build Coastguard Worker 
8255*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_FILTER:
8256*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMinFilterValue(context, entryPoint, params, false))
8257*8975f5c5SAndroid Build Coastguard Worker             {
8258*8975f5c5SAndroid Build Coastguard Worker                 return false;
8259*8975f5c5SAndroid Build Coastguard Worker             }
8260*8975f5c5SAndroid Build Coastguard Worker             break;
8261*8975f5c5SAndroid Build Coastguard Worker 
8262*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAG_FILTER:
8263*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMagFilterValue(context, entryPoint, params))
8264*8975f5c5SAndroid Build Coastguard Worker             {
8265*8975f5c5SAndroid Build Coastguard Worker                 return false;
8266*8975f5c5SAndroid Build Coastguard Worker             }
8267*8975f5c5SAndroid Build Coastguard Worker             break;
8268*8975f5c5SAndroid Build Coastguard Worker 
8269*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_LOD:
8270*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LOD:
8271*8975f5c5SAndroid Build Coastguard Worker             // any value is permissible
8272*8975f5c5SAndroid Build Coastguard Worker             break;
8273*8975f5c5SAndroid Build Coastguard Worker 
8274*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_MODE:
8275*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureCompareModeValue(context, entryPoint, params))
8276*8975f5c5SAndroid Build Coastguard Worker             {
8277*8975f5c5SAndroid Build Coastguard Worker                 return false;
8278*8975f5c5SAndroid Build Coastguard Worker             }
8279*8975f5c5SAndroid Build Coastguard Worker             break;
8280*8975f5c5SAndroid Build Coastguard Worker 
8281*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_FUNC:
8282*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureCompareFuncValue(context, entryPoint, params))
8283*8975f5c5SAndroid Build Coastguard Worker             {
8284*8975f5c5SAndroid Build Coastguard Worker                 return false;
8285*8975f5c5SAndroid Build Coastguard Worker             }
8286*8975f5c5SAndroid Build Coastguard Worker             break;
8287*8975f5c5SAndroid Build Coastguard Worker 
8288*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SRGB_DECODE_EXT:
8289*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureSRGBDecodeValue(context, entryPoint, params))
8290*8975f5c5SAndroid Build Coastguard Worker             {
8291*8975f5c5SAndroid Build Coastguard Worker                 return false;
8292*8975f5c5SAndroid Build Coastguard Worker             }
8293*8975f5c5SAndroid Build Coastguard Worker             break;
8294*8975f5c5SAndroid Build Coastguard Worker 
8295*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
8296*8975f5c5SAndroid Build Coastguard Worker         {
8297*8975f5c5SAndroid Build Coastguard Worker             GLfloat paramValue = static_cast<GLfloat>(params[0]);
8298*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMaxAnisotropyValue(context, entryPoint, paramValue))
8299*8975f5c5SAndroid Build Coastguard Worker             {
8300*8975f5c5SAndroid Build Coastguard Worker                 return false;
8301*8975f5c5SAndroid Build Coastguard Worker             }
8302*8975f5c5SAndroid Build Coastguard Worker         }
8303*8975f5c5SAndroid Build Coastguard Worker         break;
8304*8975f5c5SAndroid Build Coastguard Worker 
8305*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BORDER_COLOR:
8306*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureBorderClampAny() &&
8307*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
8308*8975f5c5SAndroid Build Coastguard Worker             {
8309*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
8310*8975f5c5SAndroid Build Coastguard Worker                 return false;
8311*8975f5c5SAndroid Build Coastguard Worker             }
8312*8975f5c5SAndroid Build Coastguard Worker             if (!vectorParams)
8313*8975f5c5SAndroid Build Coastguard Worker             {
8314*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInsufficientBufferSize);
8315*8975f5c5SAndroid Build Coastguard Worker                 return false;
8316*8975f5c5SAndroid Build Coastguard Worker             }
8317*8975f5c5SAndroid Build Coastguard Worker             break;
8318*8975f5c5SAndroid Build Coastguard Worker 
8319*8975f5c5SAndroid Build Coastguard Worker         default:
8320*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8321*8975f5c5SAndroid Build Coastguard Worker             return false;
8322*8975f5c5SAndroid Build Coastguard Worker     }
8323*8975f5c5SAndroid Build Coastguard Worker 
8324*8975f5c5SAndroid Build Coastguard Worker     return true;
8325*8975f5c5SAndroid Build Coastguard Worker }
8326*8975f5c5SAndroid Build Coastguard Worker 
8327*8975f5c5SAndroid Build Coastguard Worker template bool ValidateSamplerParameterBase(const Context *,
8328*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint,
8329*8975f5c5SAndroid Build Coastguard Worker                                            SamplerID,
8330*8975f5c5SAndroid Build Coastguard Worker                                            GLenum,
8331*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei,
8332*8975f5c5SAndroid Build Coastguard Worker                                            bool,
8333*8975f5c5SAndroid Build Coastguard Worker                                            const GLfloat *);
8334*8975f5c5SAndroid Build Coastguard Worker template bool ValidateSamplerParameterBase(const Context *,
8335*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint,
8336*8975f5c5SAndroid Build Coastguard Worker                                            SamplerID,
8337*8975f5c5SAndroid Build Coastguard Worker                                            GLenum,
8338*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei,
8339*8975f5c5SAndroid Build Coastguard Worker                                            bool,
8340*8975f5c5SAndroid Build Coastguard Worker                                            const GLint *);
8341*8975f5c5SAndroid Build Coastguard Worker template bool ValidateSamplerParameterBase(const Context *,
8342*8975f5c5SAndroid Build Coastguard Worker                                            angle::EntryPoint,
8343*8975f5c5SAndroid Build Coastguard Worker                                            SamplerID,
8344*8975f5c5SAndroid Build Coastguard Worker                                            GLenum,
8345*8975f5c5SAndroid Build Coastguard Worker                                            GLsizei,
8346*8975f5c5SAndroid Build Coastguard Worker                                            bool,
8347*8975f5c5SAndroid Build Coastguard Worker                                            const GLuint *);
8348*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetSamplerParameterBase(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLsizei * length)8349*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetSamplerParameterBase(const Context *context,
8350*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
8351*8975f5c5SAndroid Build Coastguard Worker                                      SamplerID sampler,
8352*8975f5c5SAndroid Build Coastguard Worker                                      GLenum pname,
8353*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei *length)
8354*8975f5c5SAndroid Build Coastguard Worker {
8355*8975f5c5SAndroid Build Coastguard Worker     if (length)
8356*8975f5c5SAndroid Build Coastguard Worker     {
8357*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
8358*8975f5c5SAndroid Build Coastguard Worker     }
8359*8975f5c5SAndroid Build Coastguard Worker 
8360*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() < 3)
8361*8975f5c5SAndroid Build Coastguard Worker     {
8362*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8363*8975f5c5SAndroid Build Coastguard Worker         return false;
8364*8975f5c5SAndroid Build Coastguard Worker     }
8365*8975f5c5SAndroid Build Coastguard Worker 
8366*8975f5c5SAndroid Build Coastguard Worker     if (!context->isSampler(sampler))
8367*8975f5c5SAndroid Build Coastguard Worker     {
8368*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSampler);
8369*8975f5c5SAndroid Build Coastguard Worker         return false;
8370*8975f5c5SAndroid Build Coastguard Worker     }
8371*8975f5c5SAndroid Build Coastguard Worker 
8372*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
8373*8975f5c5SAndroid Build Coastguard Worker     {
8374*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_S:
8375*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_T:
8376*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WRAP_R:
8377*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_FILTER:
8378*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAG_FILTER:
8379*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MIN_LOD:
8380*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_LOD:
8381*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_MODE:
8382*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPARE_FUNC:
8383*8975f5c5SAndroid Build Coastguard Worker             break;
8384*8975f5c5SAndroid Build Coastguard Worker 
8385*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
8386*8975f5c5SAndroid Build Coastguard Worker             if (!ValidateTextureMaxAnisotropyExtensionEnabled(context, entryPoint))
8387*8975f5c5SAndroid Build Coastguard Worker             {
8388*8975f5c5SAndroid Build Coastguard Worker                 return false;
8389*8975f5c5SAndroid Build Coastguard Worker             }
8390*8975f5c5SAndroid Build Coastguard Worker             break;
8391*8975f5c5SAndroid Build Coastguard Worker 
8392*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SRGB_DECODE_EXT:
8393*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureSRGBDecodeEXT)
8394*8975f5c5SAndroid Build Coastguard Worker             {
8395*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8396*8975f5c5SAndroid Build Coastguard Worker                 return false;
8397*8975f5c5SAndroid Build Coastguard Worker             }
8398*8975f5c5SAndroid Build Coastguard Worker             break;
8399*8975f5c5SAndroid Build Coastguard Worker 
8400*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BORDER_COLOR:
8401*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureBorderClampAny() &&
8402*8975f5c5SAndroid Build Coastguard Worker                 context->getClientVersion() < ES_3_2)
8403*8975f5c5SAndroid Build Coastguard Worker             {
8404*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
8405*8975f5c5SAndroid Build Coastguard Worker                 return false;
8406*8975f5c5SAndroid Build Coastguard Worker             }
8407*8975f5c5SAndroid Build Coastguard Worker             break;
8408*8975f5c5SAndroid Build Coastguard Worker 
8409*8975f5c5SAndroid Build Coastguard Worker         default:
8410*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8411*8975f5c5SAndroid Build Coastguard Worker             return false;
8412*8975f5c5SAndroid Build Coastguard Worker     }
8413*8975f5c5SAndroid Build Coastguard Worker 
8414*8975f5c5SAndroid Build Coastguard Worker     if (length)
8415*8975f5c5SAndroid Build Coastguard Worker     {
8416*8975f5c5SAndroid Build Coastguard Worker         *length = GetSamplerParameterCount(pname);
8417*8975f5c5SAndroid Build Coastguard Worker     }
8418*8975f5c5SAndroid Build Coastguard Worker     return true;
8419*8975f5c5SAndroid Build Coastguard Worker }
8420*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetInternalFormativBase(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,GLsizei * numParams)8421*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetInternalFormativBase(const Context *context,
8422*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
8423*8975f5c5SAndroid Build Coastguard Worker                                      GLenum target,
8424*8975f5c5SAndroid Build Coastguard Worker                                      GLenum internalformat,
8425*8975f5c5SAndroid Build Coastguard Worker                                      GLenum pname,
8426*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei bufSize,
8427*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei *numParams)
8428*8975f5c5SAndroid Build Coastguard Worker {
8429*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
8430*8975f5c5SAndroid Build Coastguard Worker     {
8431*8975f5c5SAndroid Build Coastguard Worker         *numParams = 0;
8432*8975f5c5SAndroid Build Coastguard Worker     }
8433*8975f5c5SAndroid Build Coastguard Worker 
8434*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() < 3)
8435*8975f5c5SAndroid Build Coastguard Worker     {
8436*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
8437*8975f5c5SAndroid Build Coastguard Worker         return false;
8438*8975f5c5SAndroid Build Coastguard Worker     }
8439*8975f5c5SAndroid Build Coastguard Worker 
8440*8975f5c5SAndroid Build Coastguard Worker     const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
8441*8975f5c5SAndroid Build Coastguard Worker     if (!formatCaps.renderbuffer)
8442*8975f5c5SAndroid Build Coastguard Worker     {
8443*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kFormatNotRenderable);
8444*8975f5c5SAndroid Build Coastguard Worker         return false;
8445*8975f5c5SAndroid Build Coastguard Worker     }
8446*8975f5c5SAndroid Build Coastguard Worker 
8447*8975f5c5SAndroid Build Coastguard Worker     switch (target)
8448*8975f5c5SAndroid Build Coastguard Worker     {
8449*8975f5c5SAndroid Build Coastguard Worker         case GL_RENDERBUFFER:
8450*8975f5c5SAndroid Build Coastguard Worker             break;
8451*8975f5c5SAndroid Build Coastguard Worker 
8452*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D_MULTISAMPLE:
8453*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_1 &&
8454*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().textureMultisampleANGLE)
8455*8975f5c5SAndroid Build Coastguard Worker             {
8456*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
8457*8975f5c5SAndroid Build Coastguard Worker                 return false;
8458*8975f5c5SAndroid Build Coastguard Worker             }
8459*8975f5c5SAndroid Build Coastguard Worker             break;
8460*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
8461*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_2 &&
8462*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().textureStorageMultisample2dArrayOES)
8463*8975f5c5SAndroid Build Coastguard Worker             {
8464*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleArrayExtensionOrES32Required);
8465*8975f5c5SAndroid Build Coastguard Worker                 return false;
8466*8975f5c5SAndroid Build Coastguard Worker             }
8467*8975f5c5SAndroid Build Coastguard Worker             break;
8468*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D:
8469*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_CUBE_MAP:
8470*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_3D:
8471*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_2D_ARRAY:
8472*8975f5c5SAndroid Build Coastguard Worker             if (pname != GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT &&
8473*8975f5c5SAndroid Build Coastguard Worker                 pname != GL_SURFACE_COMPRESSION_EXT)
8474*8975f5c5SAndroid Build Coastguard Worker             {
8475*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8476*8975f5c5SAndroid Build Coastguard Worker                 return false;
8477*8975f5c5SAndroid Build Coastguard Worker             }
8478*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureStorageCompressionEXT)
8479*8975f5c5SAndroid Build Coastguard Worker             {
8480*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8481*8975f5c5SAndroid Build Coastguard Worker                                        kTextureStorageCompressionExtensionRequired);
8482*8975f5c5SAndroid Build Coastguard Worker                 return false;
8483*8975f5c5SAndroid Build Coastguard Worker             }
8484*8975f5c5SAndroid Build Coastguard Worker             break;
8485*8975f5c5SAndroid Build Coastguard Worker         default:
8486*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8487*8975f5c5SAndroid Build Coastguard Worker             return false;
8488*8975f5c5SAndroid Build Coastguard Worker     }
8489*8975f5c5SAndroid Build Coastguard Worker 
8490*8975f5c5SAndroid Build Coastguard Worker     if (bufSize < 0)
8491*8975f5c5SAndroid Build Coastguard Worker     {
8492*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInsufficientBufferSize);
8493*8975f5c5SAndroid Build Coastguard Worker         return false;
8494*8975f5c5SAndroid Build Coastguard Worker     }
8495*8975f5c5SAndroid Build Coastguard Worker 
8496*8975f5c5SAndroid Build Coastguard Worker     GLsizei maxWriteParams = 0;
8497*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
8498*8975f5c5SAndroid Build Coastguard Worker     {
8499*8975f5c5SAndroid Build Coastguard Worker         case GL_NUM_SAMPLE_COUNTS:
8500*8975f5c5SAndroid Build Coastguard Worker             maxWriteParams = 1;
8501*8975f5c5SAndroid Build Coastguard Worker             break;
8502*8975f5c5SAndroid Build Coastguard Worker 
8503*8975f5c5SAndroid Build Coastguard Worker         case GL_SAMPLES:
8504*8975f5c5SAndroid Build Coastguard Worker             maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
8505*8975f5c5SAndroid Build Coastguard Worker             break;
8506*8975f5c5SAndroid Build Coastguard Worker 
8507*8975f5c5SAndroid Build Coastguard Worker         case GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT:
8508*8975f5c5SAndroid Build Coastguard Worker         case GL_SURFACE_COMPRESSION_EXT:
8509*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().textureStorageCompressionEXT)
8510*8975f5c5SAndroid Build Coastguard Worker             {
8511*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8512*8975f5c5SAndroid Build Coastguard Worker                                        kTextureStorageCompressionExtensionRequired);
8513*8975f5c5SAndroid Build Coastguard Worker                 return false;
8514*8975f5c5SAndroid Build Coastguard Worker             }
8515*8975f5c5SAndroid Build Coastguard Worker             break;
8516*8975f5c5SAndroid Build Coastguard Worker 
8517*8975f5c5SAndroid Build Coastguard Worker         default:
8518*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
8519*8975f5c5SAndroid Build Coastguard Worker             return false;
8520*8975f5c5SAndroid Build Coastguard Worker     }
8521*8975f5c5SAndroid Build Coastguard Worker 
8522*8975f5c5SAndroid Build Coastguard Worker     if (numParams)
8523*8975f5c5SAndroid Build Coastguard Worker     {
8524*8975f5c5SAndroid Build Coastguard Worker         // glGetInternalFormativ will not overflow bufSize
8525*8975f5c5SAndroid Build Coastguard Worker         *numParams = std::min(bufSize, maxWriteParams);
8526*8975f5c5SAndroid Build Coastguard Worker     }
8527*8975f5c5SAndroid Build Coastguard Worker 
8528*8975f5c5SAndroid Build Coastguard Worker     return true;
8529*8975f5c5SAndroid Build Coastguard Worker }
8530*8975f5c5SAndroid Build Coastguard Worker 
ValidateFramebufferNotMultisampled(const Context * context,angle::EntryPoint entryPoint,const Framebuffer * framebuffer,bool checkReadBufferResourceSamples)8531*8975f5c5SAndroid Build Coastguard Worker bool ValidateFramebufferNotMultisampled(const Context *context,
8532*8975f5c5SAndroid Build Coastguard Worker                                         angle::EntryPoint entryPoint,
8533*8975f5c5SAndroid Build Coastguard Worker                                         const Framebuffer *framebuffer,
8534*8975f5c5SAndroid Build Coastguard Worker                                         bool checkReadBufferResourceSamples)
8535*8975f5c5SAndroid Build Coastguard Worker {
8536*8975f5c5SAndroid Build Coastguard Worker     int samples = checkReadBufferResourceSamples
8537*8975f5c5SAndroid Build Coastguard Worker                       ? framebuffer->getReadBufferResourceSamples(context)
8538*8975f5c5SAndroid Build Coastguard Worker                       : framebuffer->getSamples(context);
8539*8975f5c5SAndroid Build Coastguard Worker     if (samples != 0)
8540*8975f5c5SAndroid Build Coastguard Worker     {
8541*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
8542*8975f5c5SAndroid Build Coastguard Worker         return false;
8543*8975f5c5SAndroid Build Coastguard Worker     }
8544*8975f5c5SAndroid Build Coastguard Worker     return true;
8545*8975f5c5SAndroid Build Coastguard Worker }
8546*8975f5c5SAndroid Build Coastguard Worker 
ValidateMultitextureUnit(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum texture)8547*8975f5c5SAndroid Build Coastguard Worker bool ValidateMultitextureUnit(const PrivateState &state,
8548*8975f5c5SAndroid Build Coastguard Worker                               ErrorSet *errors,
8549*8975f5c5SAndroid Build Coastguard Worker                               angle::EntryPoint entryPoint,
8550*8975f5c5SAndroid Build Coastguard Worker                               GLenum texture)
8551*8975f5c5SAndroid Build Coastguard Worker {
8552*8975f5c5SAndroid Build Coastguard Worker     if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + state.getCaps().maxMultitextureUnits)
8553*8975f5c5SAndroid Build Coastguard Worker     {
8554*8975f5c5SAndroid Build Coastguard Worker         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidMultitextureUnit);
8555*8975f5c5SAndroid Build Coastguard Worker         return false;
8556*8975f5c5SAndroid Build Coastguard Worker     }
8557*8975f5c5SAndroid Build Coastguard Worker     return true;
8558*8975f5c5SAndroid Build Coastguard Worker }
8559*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexStorageMultisample(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLint internalFormat,GLsizei width,GLsizei height)8560*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexStorageMultisample(const Context *context,
8561*8975f5c5SAndroid Build Coastguard Worker                                    angle::EntryPoint entryPoint,
8562*8975f5c5SAndroid Build Coastguard Worker                                    TextureType target,
8563*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei samples,
8564*8975f5c5SAndroid Build Coastguard Worker                                    GLint internalFormat,
8565*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei width,
8566*8975f5c5SAndroid Build Coastguard Worker                                    GLsizei height)
8567*8975f5c5SAndroid Build Coastguard Worker {
8568*8975f5c5SAndroid Build Coastguard Worker     const Caps &caps = context->getCaps();
8569*8975f5c5SAndroid Build Coastguard Worker     if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
8570*8975f5c5SAndroid Build Coastguard Worker     {
8571*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
8572*8975f5c5SAndroid Build Coastguard Worker         return false;
8573*8975f5c5SAndroid Build Coastguard Worker     }
8574*8975f5c5SAndroid Build Coastguard Worker 
8575*8975f5c5SAndroid Build Coastguard Worker     if (samples == 0)
8576*8975f5c5SAndroid Build Coastguard Worker     {
8577*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplesZero);
8578*8975f5c5SAndroid Build Coastguard Worker         return false;
8579*8975f5c5SAndroid Build Coastguard Worker     }
8580*8975f5c5SAndroid Build Coastguard Worker 
8581*8975f5c5SAndroid Build Coastguard Worker     const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
8582*8975f5c5SAndroid Build Coastguard Worker     if (!formatCaps.textureAttachment)
8583*8975f5c5SAndroid Build Coastguard Worker     {
8584*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRenderableInternalFormat);
8585*8975f5c5SAndroid Build Coastguard Worker         return false;
8586*8975f5c5SAndroid Build Coastguard Worker     }
8587*8975f5c5SAndroid Build Coastguard Worker 
8588*8975f5c5SAndroid Build Coastguard Worker     // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
8589*8975f5c5SAndroid Build Coastguard Worker     // is one of the unsized base internalformats listed in table 8.11.
8590*8975f5c5SAndroid Build Coastguard Worker     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
8591*8975f5c5SAndroid Build Coastguard Worker     if (formatInfo.internalFormat == GL_NONE)
8592*8975f5c5SAndroid Build Coastguard Worker     {
8593*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
8594*8975f5c5SAndroid Build Coastguard Worker         return false;
8595*8975f5c5SAndroid Build Coastguard Worker     }
8596*8975f5c5SAndroid Build Coastguard Worker 
8597*8975f5c5SAndroid Build Coastguard Worker     if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
8598*8975f5c5SAndroid Build Coastguard Worker     {
8599*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
8600*8975f5c5SAndroid Build Coastguard Worker         return false;
8601*8975f5c5SAndroid Build Coastguard Worker     }
8602*8975f5c5SAndroid Build Coastguard Worker 
8603*8975f5c5SAndroid Build Coastguard Worker     Texture *texture = context->getTextureByType(target);
8604*8975f5c5SAndroid Build Coastguard Worker     if (!texture || texture->id().value == 0)
8605*8975f5c5SAndroid Build Coastguard Worker     {
8606*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kZeroBoundToTarget);
8607*8975f5c5SAndroid Build Coastguard Worker         return false;
8608*8975f5c5SAndroid Build Coastguard Worker     }
8609*8975f5c5SAndroid Build Coastguard Worker 
8610*8975f5c5SAndroid Build Coastguard Worker     if (texture->getImmutableFormat())
8611*8975f5c5SAndroid Build Coastguard Worker     {
8612*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImmutableTextureBound);
8613*8975f5c5SAndroid Build Coastguard Worker         return false;
8614*8975f5c5SAndroid Build Coastguard Worker     }
8615*8975f5c5SAndroid Build Coastguard Worker     return true;
8616*8975f5c5SAndroid Build Coastguard Worker }
8617*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexStorage2DMultisampleBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLint internalFormat,GLsizei width,GLsizei height)8618*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexStorage2DMultisampleBase(const Context *context,
8619*8975f5c5SAndroid Build Coastguard Worker                                          angle::EntryPoint entryPoint,
8620*8975f5c5SAndroid Build Coastguard Worker                                          TextureType target,
8621*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei samples,
8622*8975f5c5SAndroid Build Coastguard Worker                                          GLint internalFormat,
8623*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei width,
8624*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei height)
8625*8975f5c5SAndroid Build Coastguard Worker {
8626*8975f5c5SAndroid Build Coastguard Worker     if (target != TextureType::_2DMultisample)
8627*8975f5c5SAndroid Build Coastguard Worker     {
8628*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8629*8975f5c5SAndroid Build Coastguard Worker         return false;
8630*8975f5c5SAndroid Build Coastguard Worker     }
8631*8975f5c5SAndroid Build Coastguard Worker 
8632*8975f5c5SAndroid Build Coastguard Worker     if (width < 1 || height < 1)
8633*8975f5c5SAndroid Build Coastguard Worker     {
8634*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
8635*8975f5c5SAndroid Build Coastguard Worker         return false;
8636*8975f5c5SAndroid Build Coastguard Worker     }
8637*8975f5c5SAndroid Build Coastguard Worker 
8638*8975f5c5SAndroid Build Coastguard Worker     return ValidateTexStorageMultisample(context, entryPoint, target, samples, internalFormat,
8639*8975f5c5SAndroid Build Coastguard Worker                                          width, height);
8640*8975f5c5SAndroid Build Coastguard Worker }
8641*8975f5c5SAndroid Build Coastguard Worker 
ValidateTexStorage3DMultisampleBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)8642*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexStorage3DMultisampleBase(const Context *context,
8643*8975f5c5SAndroid Build Coastguard Worker                                          angle::EntryPoint entryPoint,
8644*8975f5c5SAndroid Build Coastguard Worker                                          TextureType target,
8645*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei samples,
8646*8975f5c5SAndroid Build Coastguard Worker                                          GLenum internalformat,
8647*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei width,
8648*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei height,
8649*8975f5c5SAndroid Build Coastguard Worker                                          GLsizei depth)
8650*8975f5c5SAndroid Build Coastguard Worker {
8651*8975f5c5SAndroid Build Coastguard Worker     if (target != TextureType::_2DMultisampleArray)
8652*8975f5c5SAndroid Build Coastguard Worker     {
8653*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTarget);
8654*8975f5c5SAndroid Build Coastguard Worker         return false;
8655*8975f5c5SAndroid Build Coastguard Worker     }
8656*8975f5c5SAndroid Build Coastguard Worker 
8657*8975f5c5SAndroid Build Coastguard Worker     if (width < 1 || height < 1 || depth < 1)
8658*8975f5c5SAndroid Build Coastguard Worker     {
8659*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
8660*8975f5c5SAndroid Build Coastguard Worker         return false;
8661*8975f5c5SAndroid Build Coastguard Worker     }
8662*8975f5c5SAndroid Build Coastguard Worker 
8663*8975f5c5SAndroid Build Coastguard Worker     if (depth > context->getCaps().maxArrayTextureLayers)
8664*8975f5c5SAndroid Build Coastguard Worker     {
8665*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureDepthOutOfRange);
8666*8975f5c5SAndroid Build Coastguard Worker         return false;
8667*8975f5c5SAndroid Build Coastguard Worker     }
8668*8975f5c5SAndroid Build Coastguard Worker 
8669*8975f5c5SAndroid Build Coastguard Worker     return ValidateTexStorageMultisample(context, entryPoint, target, samples, internalformat,
8670*8975f5c5SAndroid Build Coastguard Worker                                          width, height);
8671*8975f5c5SAndroid Build Coastguard Worker }
8672*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetTexLevelParameterBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum pname,GLsizei * length)8673*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetTexLevelParameterBase(const Context *context,
8674*8975f5c5SAndroid Build Coastguard Worker                                       angle::EntryPoint entryPoint,
8675*8975f5c5SAndroid Build Coastguard Worker                                       TextureTarget target,
8676*8975f5c5SAndroid Build Coastguard Worker                                       GLint level,
8677*8975f5c5SAndroid Build Coastguard Worker                                       GLenum pname,
8678*8975f5c5SAndroid Build Coastguard Worker                                       GLsizei *length)
8679*8975f5c5SAndroid Build Coastguard Worker {
8680*8975f5c5SAndroid Build Coastguard Worker 
8681*8975f5c5SAndroid Build Coastguard Worker     if (length)
8682*8975f5c5SAndroid Build Coastguard Worker     {
8683*8975f5c5SAndroid Build Coastguard Worker         *length = 0;
8684*8975f5c5SAndroid Build Coastguard Worker     }
8685*8975f5c5SAndroid Build Coastguard Worker 
8686*8975f5c5SAndroid Build Coastguard Worker     TextureType type = TextureTargetToType(target);
8687*8975f5c5SAndroid Build Coastguard Worker 
8688*8975f5c5SAndroid Build Coastguard Worker     if (!ValidTexLevelDestinationTarget(context, type))
8689*8975f5c5SAndroid Build Coastguard Worker     {
8690*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
8691*8975f5c5SAndroid Build Coastguard Worker         return false;
8692*8975f5c5SAndroid Build Coastguard Worker     }
8693*8975f5c5SAndroid Build Coastguard Worker 
8694*8975f5c5SAndroid Build Coastguard Worker     // If type is valid, the texture object must exist
8695*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context->getTextureByType(type) != nullptr);
8696*8975f5c5SAndroid Build Coastguard Worker 
8697*8975f5c5SAndroid Build Coastguard Worker     if (!ValidMipLevel(context, type, level))
8698*8975f5c5SAndroid Build Coastguard Worker     {
8699*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
8700*8975f5c5SAndroid Build Coastguard Worker         return false;
8701*8975f5c5SAndroid Build Coastguard Worker     }
8702*8975f5c5SAndroid Build Coastguard Worker 
8703*8975f5c5SAndroid Build Coastguard Worker     switch (pname)
8704*8975f5c5SAndroid Build Coastguard Worker     {
8705*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_RED_TYPE:
8706*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_GREEN_TYPE:
8707*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BLUE_TYPE:
8708*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_ALPHA_TYPE:
8709*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_DEPTH_TYPE:
8710*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_RED_SIZE:
8711*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_GREEN_SIZE:
8712*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BLUE_SIZE:
8713*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_ALPHA_SIZE:
8714*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_DEPTH_SIZE:
8715*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_STENCIL_SIZE:
8716*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SHARED_SIZE:
8717*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_INTERNAL_FORMAT:
8718*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_WIDTH:
8719*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_HEIGHT:
8720*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_COMPRESSED:
8721*8975f5c5SAndroid Build Coastguard Worker             break;
8722*8975f5c5SAndroid Build Coastguard Worker 
8723*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_DEPTH:
8724*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_0 && !context->getExtensions().texture3DOES)
8725*8975f5c5SAndroid Build Coastguard Worker             {
8726*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumNotSupported);
8727*8975f5c5SAndroid Build Coastguard Worker                 return false;
8728*8975f5c5SAndroid Build Coastguard Worker             }
8729*8975f5c5SAndroid Build Coastguard Worker             break;
8730*8975f5c5SAndroid Build Coastguard Worker 
8731*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_SAMPLES:
8732*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
8733*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < ES_3_1 &&
8734*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().textureMultisampleANGLE)
8735*8975f5c5SAndroid Build Coastguard Worker             {
8736*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
8737*8975f5c5SAndroid Build Coastguard Worker                 return false;
8738*8975f5c5SAndroid Build Coastguard Worker             }
8739*8975f5c5SAndroid Build Coastguard Worker             break;
8740*8975f5c5SAndroid Build Coastguard Worker 
8741*8975f5c5SAndroid Build Coastguard Worker         case GL_RESOURCE_INITIALIZED_ANGLE:
8742*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().robustResourceInitializationANGLE)
8743*8975f5c5SAndroid Build Coastguard Worker             {
8744*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM,
8745*8975f5c5SAndroid Build Coastguard Worker                                        kRobustResourceInitializationExtensionRequired);
8746*8975f5c5SAndroid Build Coastguard Worker                 return false;
8747*8975f5c5SAndroid Build Coastguard Worker             }
8748*8975f5c5SAndroid Build Coastguard Worker             break;
8749*8975f5c5SAndroid Build Coastguard Worker 
8750*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
8751*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BUFFER_OFFSET:
8752*8975f5c5SAndroid Build Coastguard Worker         case GL_TEXTURE_BUFFER_SIZE:
8753*8975f5c5SAndroid Build Coastguard Worker             if (context->getClientVersion() < Version(3, 2) &&
8754*8975f5c5SAndroid Build Coastguard Worker                 !context->getExtensions().textureBufferAny())
8755*8975f5c5SAndroid Build Coastguard Worker             {
8756*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferExtensionNotAvailable);
8757*8975f5c5SAndroid Build Coastguard Worker                 return false;
8758*8975f5c5SAndroid Build Coastguard Worker             }
8759*8975f5c5SAndroid Build Coastguard Worker             break;
8760*8975f5c5SAndroid Build Coastguard Worker 
8761*8975f5c5SAndroid Build Coastguard Worker         default:
8762*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
8763*8975f5c5SAndroid Build Coastguard Worker             return false;
8764*8975f5c5SAndroid Build Coastguard Worker     }
8765*8975f5c5SAndroid Build Coastguard Worker 
8766*8975f5c5SAndroid Build Coastguard Worker     if (length)
8767*8975f5c5SAndroid Build Coastguard Worker     {
8768*8975f5c5SAndroid Build Coastguard Worker         *length = 1;
8769*8975f5c5SAndroid Build Coastguard Worker     }
8770*8975f5c5SAndroid Build Coastguard Worker     return true;
8771*8975f5c5SAndroid Build Coastguard Worker }
8772*8975f5c5SAndroid Build Coastguard Worker 
ValidateGetMultisamplefvBase(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLuint index,const GLfloat * val)8773*8975f5c5SAndroid Build Coastguard Worker bool ValidateGetMultisamplefvBase(const Context *context,
8774*8975f5c5SAndroid Build Coastguard Worker                                   angle::EntryPoint entryPoint,
8775*8975f5c5SAndroid Build Coastguard Worker                                   GLenum pname,
8776*8975f5c5SAndroid Build Coastguard Worker                                   GLuint index,
8777*8975f5c5SAndroid Build Coastguard Worker                                   const GLfloat *val)
8778*8975f5c5SAndroid Build Coastguard Worker {
8779*8975f5c5SAndroid Build Coastguard Worker     if (pname != GL_SAMPLE_POSITION)
8780*8975f5c5SAndroid Build Coastguard Worker     {
8781*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
8782*8975f5c5SAndroid Build Coastguard Worker         return false;
8783*8975f5c5SAndroid Build Coastguard Worker     }
8784*8975f5c5SAndroid Build Coastguard Worker 
8785*8975f5c5SAndroid Build Coastguard Worker     Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
8786*8975f5c5SAndroid Build Coastguard Worker     GLint samples            = framebuffer->getSamples(context);
8787*8975f5c5SAndroid Build Coastguard Worker 
8788*8975f5c5SAndroid Build Coastguard Worker     if (index >= static_cast<GLuint>(samples))
8789*8975f5c5SAndroid Build Coastguard Worker     {
8790*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsSamples);
8791*8975f5c5SAndroid Build Coastguard Worker         return false;
8792*8975f5c5SAndroid Build Coastguard Worker     }
8793*8975f5c5SAndroid Build Coastguard Worker 
8794*8975f5c5SAndroid Build Coastguard Worker     return true;
8795*8975f5c5SAndroid Build Coastguard Worker }
8796*8975f5c5SAndroid Build Coastguard Worker 
ValidateSampleMaskiBase(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint maskNumber,GLbitfield mask)8797*8975f5c5SAndroid Build Coastguard Worker bool ValidateSampleMaskiBase(const PrivateState &state,
8798*8975f5c5SAndroid Build Coastguard Worker                              ErrorSet *errors,
8799*8975f5c5SAndroid Build Coastguard Worker                              angle::EntryPoint entryPoint,
8800*8975f5c5SAndroid Build Coastguard Worker                              GLuint maskNumber,
8801*8975f5c5SAndroid Build Coastguard Worker                              GLbitfield mask)
8802*8975f5c5SAndroid Build Coastguard Worker {
8803*8975f5c5SAndroid Build Coastguard Worker     if (maskNumber >= static_cast<GLuint>(state.getCaps().maxSampleMaskWords))
8804*8975f5c5SAndroid Build Coastguard Worker     {
8805*8975f5c5SAndroid Build Coastguard Worker         errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidSampleMaskNumber);
8806*8975f5c5SAndroid Build Coastguard Worker         return false;
8807*8975f5c5SAndroid Build Coastguard Worker     }
8808*8975f5c5SAndroid Build Coastguard Worker 
8809*8975f5c5SAndroid Build Coastguard Worker     return true;
8810*8975f5c5SAndroid Build Coastguard Worker }
8811*8975f5c5SAndroid Build Coastguard Worker 
RecordDrawAttribsError(const Context * context,angle::EntryPoint entryPoint)8812*8975f5c5SAndroid Build Coastguard Worker void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint)
8813*8975f5c5SAndroid Build Coastguard Worker {
8814*8975f5c5SAndroid Build Coastguard Worker     // An overflow can happen when adding the offset. Check against a special constant.
8815*8975f5c5SAndroid Build Coastguard Worker     if (context->getStateCache().getNonInstancedVertexElementLimit() ==
8816*8975f5c5SAndroid Build Coastguard Worker             VertexAttribute::kIntegerOverflow ||
8817*8975f5c5SAndroid Build Coastguard Worker         context->getStateCache().getInstancedVertexElementLimit() ==
8818*8975f5c5SAndroid Build Coastguard Worker             VertexAttribute::kIntegerOverflow)
8819*8975f5c5SAndroid Build Coastguard Worker     {
8820*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
8821*8975f5c5SAndroid Build Coastguard Worker     }
8822*8975f5c5SAndroid Build Coastguard Worker     else
8823*8975f5c5SAndroid Build Coastguard Worker     {
8824*8975f5c5SAndroid Build Coastguard Worker         // [OpenGL ES 3.0.2] section 2.9.4 page 40:
8825*8975f5c5SAndroid Build Coastguard Worker         // We can return INVALID_OPERATION if our buffer does not have enough backing data.
8826*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
8827*8975f5c5SAndroid Build Coastguard Worker     }
8828*8975f5c5SAndroid Build Coastguard Worker }
8829*8975f5c5SAndroid Build Coastguard Worker 
ValidateLoseContextCHROMIUM(const Context * context,angle::EntryPoint entryPoint,GraphicsResetStatus current,GraphicsResetStatus other)8830*8975f5c5SAndroid Build Coastguard Worker bool ValidateLoseContextCHROMIUM(const Context *context,
8831*8975f5c5SAndroid Build Coastguard Worker                                  angle::EntryPoint entryPoint,
8832*8975f5c5SAndroid Build Coastguard Worker                                  GraphicsResetStatus current,
8833*8975f5c5SAndroid Build Coastguard Worker                                  GraphicsResetStatus other)
8834*8975f5c5SAndroid Build Coastguard Worker {
8835*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().loseContextCHROMIUM)
8836*8975f5c5SAndroid Build Coastguard Worker     {
8837*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
8838*8975f5c5SAndroid Build Coastguard Worker         return false;
8839*8975f5c5SAndroid Build Coastguard Worker     }
8840*8975f5c5SAndroid Build Coastguard Worker 
8841*8975f5c5SAndroid Build Coastguard Worker     switch (current)
8842*8975f5c5SAndroid Build Coastguard Worker     {
8843*8975f5c5SAndroid Build Coastguard Worker         case GraphicsResetStatus::GuiltyContextReset:
8844*8975f5c5SAndroid Build Coastguard Worker         case GraphicsResetStatus::InnocentContextReset:
8845*8975f5c5SAndroid Build Coastguard Worker         case GraphicsResetStatus::UnknownContextReset:
8846*8975f5c5SAndroid Build Coastguard Worker             break;
8847*8975f5c5SAndroid Build Coastguard Worker 
8848*8975f5c5SAndroid Build Coastguard Worker         default:
8849*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidResetStatus);
8850*8975f5c5SAndroid Build Coastguard Worker     }
8851*8975f5c5SAndroid Build Coastguard Worker 
8852*8975f5c5SAndroid Build Coastguard Worker     switch (other)
8853*8975f5c5SAndroid Build Coastguard Worker     {
8854*8975f5c5SAndroid Build Coastguard Worker         case GraphicsResetStatus::GuiltyContextReset:
8855*8975f5c5SAndroid Build Coastguard Worker         case GraphicsResetStatus::InnocentContextReset:
8856*8975f5c5SAndroid Build Coastguard Worker         case GraphicsResetStatus::UnknownContextReset:
8857*8975f5c5SAndroid Build Coastguard Worker             break;
8858*8975f5c5SAndroid Build Coastguard Worker 
8859*8975f5c5SAndroid Build Coastguard Worker         default:
8860*8975f5c5SAndroid Build Coastguard Worker             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidResetStatus);
8861*8975f5c5SAndroid Build Coastguard Worker     }
8862*8975f5c5SAndroid Build Coastguard Worker 
8863*8975f5c5SAndroid Build Coastguard Worker     return true;
8864*8975f5c5SAndroid Build Coastguard Worker }
8865*8975f5c5SAndroid Build Coastguard Worker 
8866*8975f5c5SAndroid Build Coastguard Worker // GL_ANGLE_texture_storage_external
ValidateTexImage2DExternalANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type)8867*8975f5c5SAndroid Build Coastguard Worker bool ValidateTexImage2DExternalANGLE(const Context *context,
8868*8975f5c5SAndroid Build Coastguard Worker                                      angle::EntryPoint entryPoint,
8869*8975f5c5SAndroid Build Coastguard Worker                                      TextureTarget target,
8870*8975f5c5SAndroid Build Coastguard Worker                                      GLint level,
8871*8975f5c5SAndroid Build Coastguard Worker                                      GLint internalformat,
8872*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei width,
8873*8975f5c5SAndroid Build Coastguard Worker                                      GLsizei height,
8874*8975f5c5SAndroid Build Coastguard Worker                                      GLint border,
8875*8975f5c5SAndroid Build Coastguard Worker                                      GLenum format,
8876*8975f5c5SAndroid Build Coastguard Worker                                      GLenum type)
8877*8975f5c5SAndroid Build Coastguard Worker {
8878*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().textureExternalUpdateANGLE)
8879*8975f5c5SAndroid Build Coastguard Worker     {
8880*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
8881*8975f5c5SAndroid Build Coastguard Worker         return false;
8882*8975f5c5SAndroid Build Coastguard Worker     }
8883*8975f5c5SAndroid Build Coastguard Worker 
8884*8975f5c5SAndroid Build Coastguard Worker     if (!ValidTexture2DDestinationTarget(context, target) &&
8885*8975f5c5SAndroid Build Coastguard Worker         !ValidTextureExternalTarget(context, target))
8886*8975f5c5SAndroid Build Coastguard Worker     {
8887*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
8888*8975f5c5SAndroid Build Coastguard Worker         return false;
8889*8975f5c5SAndroid Build Coastguard Worker     }
8890*8975f5c5SAndroid Build Coastguard Worker 
8891*8975f5c5SAndroid Build Coastguard Worker     if (context->getClientMajorVersion() <= 2)
8892*8975f5c5SAndroid Build Coastguard Worker     {
8893*8975f5c5SAndroid Build Coastguard Worker         if (!ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat,
8894*8975f5c5SAndroid Build Coastguard Worker                                                false, false, 0, 0, width, height, border, format,
8895*8975f5c5SAndroid Build Coastguard Worker                                                type, -1, nullptr))
8896*8975f5c5SAndroid Build Coastguard Worker         {
8897*8975f5c5SAndroid Build Coastguard Worker             return false;
8898*8975f5c5SAndroid Build Coastguard Worker         }
8899*8975f5c5SAndroid Build Coastguard Worker     }
8900*8975f5c5SAndroid Build Coastguard Worker     else
8901*8975f5c5SAndroid Build Coastguard Worker     {
8902*8975f5c5SAndroid Build Coastguard Worker         if (!ValidateES3TexImageParametersBase(context, entryPoint, target, level, internalformat,
8903*8975f5c5SAndroid Build Coastguard Worker                                                false, false, 0, 0, 0, width, height, 1, border,
8904*8975f5c5SAndroid Build Coastguard Worker                                                format, type, -1, nullptr))
8905*8975f5c5SAndroid Build Coastguard Worker         {
8906*8975f5c5SAndroid Build Coastguard Worker             return false;
8907*8975f5c5SAndroid Build Coastguard Worker         }
8908*8975f5c5SAndroid Build Coastguard Worker     }
8909*8975f5c5SAndroid Build Coastguard Worker 
8910*8975f5c5SAndroid Build Coastguard Worker     return true;
8911*8975f5c5SAndroid Build Coastguard Worker }
8912*8975f5c5SAndroid Build Coastguard Worker 
ValidateInvalidateTextureANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target)8913*8975f5c5SAndroid Build Coastguard Worker bool ValidateInvalidateTextureANGLE(const Context *context,
8914*8975f5c5SAndroid Build Coastguard Worker                                     angle::EntryPoint entryPoint,
8915*8975f5c5SAndroid Build Coastguard Worker                                     TextureType target)
8916*8975f5c5SAndroid Build Coastguard Worker {
8917*8975f5c5SAndroid Build Coastguard Worker     if (!context->getExtensions().textureExternalUpdateANGLE)
8918*8975f5c5SAndroid Build Coastguard Worker     {
8919*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
8920*8975f5c5SAndroid Build Coastguard Worker         return false;
8921*8975f5c5SAndroid Build Coastguard Worker     }
8922*8975f5c5SAndroid Build Coastguard Worker 
8923*8975f5c5SAndroid Build Coastguard Worker     if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
8924*8975f5c5SAndroid Build Coastguard Worker     {
8925*8975f5c5SAndroid Build Coastguard Worker         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
8926*8975f5c5SAndroid Build Coastguard Worker         return false;
8927*8975f5c5SAndroid Build Coastguard Worker     }
8928*8975f5c5SAndroid Build Coastguard Worker 
8929*8975f5c5SAndroid Build Coastguard Worker     return true;
8930*8975f5c5SAndroid Build Coastguard Worker }
8931*8975f5c5SAndroid Build Coastguard Worker 
ValidateProgramExecutableXFBBuffersPresent(const Context * context,const ProgramExecutable * programExecutable)8932*8975f5c5SAndroid Build Coastguard Worker bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
8933*8975f5c5SAndroid Build Coastguard Worker                                                 const ProgramExecutable *programExecutable)
8934*8975f5c5SAndroid Build Coastguard Worker {
8935*8975f5c5SAndroid Build Coastguard Worker     size_t programXfbCount = programExecutable->getTransformFeedbackBufferCount();
8936*8975f5c5SAndroid Build Coastguard Worker     const TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
8937*8975f5c5SAndroid Build Coastguard Worker     for (size_t programXfbIndex = 0; programXfbIndex < programXfbCount; ++programXfbIndex)
8938*8975f5c5SAndroid Build Coastguard Worker     {
8939*8975f5c5SAndroid Build Coastguard Worker         const OffsetBindingPointer<Buffer> &buffer =
8940*8975f5c5SAndroid Build Coastguard Worker             transformFeedback->getIndexedBuffer(programXfbIndex);
8941*8975f5c5SAndroid Build Coastguard Worker         if (!buffer.get())
8942*8975f5c5SAndroid Build Coastguard Worker         {
8943*8975f5c5SAndroid Build Coastguard Worker             return false;
8944*8975f5c5SAndroid Build Coastguard Worker         }
8945*8975f5c5SAndroid Build Coastguard Worker     }
8946*8975f5c5SAndroid Build Coastguard Worker 
8947*8975f5c5SAndroid Build Coastguard Worker     return true;
8948*8975f5c5SAndroid Build Coastguard Worker }
8949*8975f5c5SAndroid Build Coastguard Worker 
ValidateLogicOpCommon(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,LogicalOperation opcodePacked)8950*8975f5c5SAndroid Build Coastguard Worker bool ValidateLogicOpCommon(const PrivateState &state,
8951*8975f5c5SAndroid Build Coastguard Worker                            ErrorSet *errors,
8952*8975f5c5SAndroid Build Coastguard Worker                            angle::EntryPoint entryPoint,
8953*8975f5c5SAndroid Build Coastguard Worker                            LogicalOperation opcodePacked)
8954*8975f5c5SAndroid Build Coastguard Worker {
8955*8975f5c5SAndroid Build Coastguard Worker     switch (opcodePacked)
8956*8975f5c5SAndroid Build Coastguard Worker     {
8957*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::And:
8958*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::AndInverted:
8959*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::AndReverse:
8960*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Clear:
8961*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Copy:
8962*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::CopyInverted:
8963*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Equiv:
8964*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Invert:
8965*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Nand:
8966*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Noop:
8967*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Nor:
8968*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Or:
8969*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::OrInverted:
8970*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::OrReverse:
8971*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Set:
8972*8975f5c5SAndroid Build Coastguard Worker         case LogicalOperation::Xor:
8973*8975f5c5SAndroid Build Coastguard Worker             return true;
8974*8975f5c5SAndroid Build Coastguard Worker         default:
8975*8975f5c5SAndroid Build Coastguard Worker             errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidLogicOp);
8976*8975f5c5SAndroid Build Coastguard Worker             return false;
8977*8975f5c5SAndroid Build Coastguard Worker     }
8978*8975f5c5SAndroid Build Coastguard Worker }
8979*8975f5c5SAndroid Build Coastguard Worker }  // namespace gl
8980