blob: 5e20b7d80a3fcb3f34254fedb5cd36929d913a99 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES.h: Validation functions for generic OpenGL ES entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES.h"
Jamie Madille2e406c2016-06-02 13:04:10 -040010
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Context.h"
Geoff Langa8406172015-07-21 16:53:39 -040012#include "libANGLE/Display.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070013#include "libANGLE/ErrorStrings.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050014#include "libANGLE/Framebuffer.h"
15#include "libANGLE/FramebufferAttachment.h"
Geoff Langa8406172015-07-21 16:53:39 -040016#include "libANGLE/Image.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050017#include "libANGLE/Program.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040018#include "libANGLE/Query.h"
19#include "libANGLE/Texture.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/TransformFeedback.h"
21#include "libANGLE/VertexArray.h"
James Darpinian30b604d2018-03-12 17:26:57 -070022#include "libANGLE/angletypes.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/formatutils.h"
jchen10a99ed552017-09-22 08:10:32 +080024#include "libANGLE/queryconversions.h"
Lingfeng Yangf97641c2018-06-21 19:22:45 -070025#include "libANGLE/queryutils.h"
Jamie Madill778bf092018-11-14 09:54:36 -050026#include "libANGLE/validationES2_autogen.h"
27#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040028
29#include "common/mathutil.h"
30#include "common/utilities.h"
31
Jamie Madille2e406c2016-06-02 13:04:10 -040032using namespace angle;
33
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034namespace gl
35{
Jamie Madille0472f32018-11-27 16:32:45 -050036using namespace err;
37
Jamie Madill1ca74672015-07-21 15:14:11 -040038namespace
39{
Luc Ferron9dbaeba2018-02-01 07:26:59 -050040bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
41{
42 // List of compressed format that require that the texture size is smaller than or a multiple of
43 // the compressed block size.
44 switch (internalFormat)
45 {
46 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
47 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
48 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
49 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
50 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
51 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
52 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
53 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
54 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
55 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
56 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
57 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
58 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
59 case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
60 case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +030061 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
62 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
63 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
64 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Luc Ferron9dbaeba2018-02-01 07:26:59 -050065 return true;
jchen10a99ed552017-09-22 08:10:32 +080066
Luc Ferron9dbaeba2018-02-01 07:26:59 -050067 default:
68 return false;
69 }
70}
71bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
72{
73 // Compressed sub textures have additional formats that requires exact size.
74 // ES 3.1, Section 8.7, Page 171
75 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
76 IsETC2EACFormat(internalFormat);
77}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030078
79bool DifferenceCanOverflow(GLint a, GLint b)
80{
81 CheckedNumeric<GLint> checkedA(a);
82 checkedA -= b;
83 // Use negation to make sure that the difference can't overflow regardless of the order.
84 checkedA = -checkedA;
85 return !checkedA.IsValid();
86}
87
Jamie Madill16e28fd2018-09-12 11:03:05 -040088bool ValidateDrawAttribsImpl(Context *context, GLint primcount, GLint maxVertex)
Jamie Madill1ca74672015-07-21 15:14:11 -040089{
Jamie Madill51af38b2018-04-15 08:50:56 -040090 // If we're drawing zero vertices, we have enough data.
Jamie Madill2da53562018-08-01 11:34:47 -040091 ASSERT(primcount > 0);
Jamie Madill51af38b2018-04-15 08:50:56 -040092
Jamie Madill88602e62018-08-08 12:49:30 -040093 // An overflow can happen when adding the offset. Check against a special constant.
94 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
95 VertexAttribute::kIntegerOverflow ||
96 context->getStateCache().getInstancedVertexElementLimit() ==
97 VertexAttribute::kIntegerOverflow)
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040098 {
Jamie Madille0472f32018-11-27 16:32:45 -050099 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madilla2d1d2d2018-08-01 11:34:46 -0400100 return false;
101 }
102
103 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
104 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
Jamie Madille0472f32018-11-27 16:32:45 -0500105 context->validationError(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
Jamie Madilla2d1d2d2018-08-01 11:34:46 -0400106 return false;
Jamie Madill1ca74672015-07-21 15:14:11 -0400107}
108
Jamie Madill16e28fd2018-09-12 11:03:05 -0400109ANGLE_INLINE bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex)
110{
111 if (maxVertex <= context->getStateCache().getNonInstancedVertexElementLimit() &&
112 (primcount - 1) <= context->getStateCache().getInstancedVertexElementLimit())
113 {
114 return true;
115 }
116 else
117 {
118 return ValidateDrawAttribsImpl(context, primcount, maxVertex);
119 }
120}
121
Jamie Madill5b772312018-03-08 20:28:32 -0500122bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -0400123{
124 switch (type)
125 {
126 // Types referenced in Table 3.4 of the ES 2.0.25 spec
127 case GL_UNSIGNED_BYTE:
128 case GL_UNSIGNED_SHORT_4_4_4_4:
129 case GL_UNSIGNED_SHORT_5_5_5_1:
130 case GL_UNSIGNED_SHORT_5_6_5:
131 return context->getClientVersion() >= ES_2_0;
132
133 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
134 case GL_BYTE:
135 case GL_INT:
136 case GL_SHORT:
137 case GL_UNSIGNED_INT:
138 case GL_UNSIGNED_INT_10F_11F_11F_REV:
139 case GL_UNSIGNED_INT_24_8:
140 case GL_UNSIGNED_INT_2_10_10_10_REV:
141 case GL_UNSIGNED_INT_5_9_9_9_REV:
142 case GL_UNSIGNED_SHORT:
143 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
144 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
145 return context->getClientVersion() >= ES_3_0;
146
147 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400148 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
149 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400150
151 case GL_HALF_FLOAT:
152 return context->getClientVersion() >= ES_3_0 ||
153 context->getExtensions().textureHalfFloat;
154
155 case GL_HALF_FLOAT_OES:
156 return context->getExtensions().colorBufferHalfFloat;
157
158 default:
159 return false;
160 }
161}
162
Jamie Madill5b772312018-03-08 20:28:32 -0500163bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400164{
165 switch (format)
166 {
167 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
168 case GL_RGBA:
169 case GL_RGB:
170 case GL_ALPHA:
171 return context->getClientVersion() >= ES_2_0;
172
173 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
174 case GL_RG:
175 case GL_RED:
176 case GL_RGBA_INTEGER:
177 case GL_RGB_INTEGER:
178 case GL_RG_INTEGER:
179 case GL_RED_INTEGER:
180 return context->getClientVersion() >= ES_3_0;
181
182 case GL_SRGB_ALPHA_EXT:
183 case GL_SRGB_EXT:
184 return context->getExtensions().sRGB;
185
186 case GL_BGRA_EXT:
187 return context->getExtensions().readFormatBGRA;
188
189 default:
190 return false;
191 }
192}
193
Jamie Madill5b772312018-03-08 20:28:32 -0500194bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400195 GLenum framebufferComponentType,
196 GLenum format,
197 GLenum type)
198{
199 switch (framebufferComponentType)
200 {
201 case GL_UNSIGNED_NORMALIZED:
202 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
203 // ReadPixels with BGRA even if the extension is not present
204 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
205 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
206 type == GL_UNSIGNED_BYTE);
207
208 case GL_SIGNED_NORMALIZED:
209 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
210
211 case GL_INT:
212 return (format == GL_RGBA_INTEGER && type == GL_INT);
213
214 case GL_UNSIGNED_INT:
215 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
216
217 case GL_FLOAT:
218 return (format == GL_RGBA && type == GL_FLOAT);
219
220 default:
221 UNREACHABLE();
222 return false;
223 }
224}
225
Geoff Langc1984ed2016-10-07 12:41:00 -0400226template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400227bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400228{
229 switch (ConvertToGLenum(params[0]))
230 {
231 case GL_CLAMP_TO_EDGE:
232 break;
233
Till Rathmannb8543632018-10-02 19:46:14 +0200234 case GL_CLAMP_TO_BORDER:
235 if (!context->getExtensions().textureBorderClamp)
236 {
Jamie Madille0472f32018-11-27 16:32:45 -0500237 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +0200238 return false;
239 }
240 break;
241
Geoff Langc1984ed2016-10-07 12:41:00 -0400242 case GL_REPEAT:
243 case GL_MIRRORED_REPEAT:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400244 if (restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400245 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400246 // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
Jamie Madille0472f32018-11-27 16:32:45 -0500247 context->validationError(GL_INVALID_ENUM, kInvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400248 return false;
249 }
250 break;
251
252 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500253 context->validationError(GL_INVALID_ENUM, kInvalidTextureWrap);
Geoff Langc1984ed2016-10-07 12:41:00 -0400254 return false;
255 }
256
257 return true;
258}
259
260template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400261bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400262{
263 switch (ConvertToGLenum(params[0]))
264 {
265 case GL_NEAREST:
266 case GL_LINEAR:
267 break;
268
269 case GL_NEAREST_MIPMAP_NEAREST:
270 case GL_LINEAR_MIPMAP_NEAREST:
271 case GL_NEAREST_MIPMAP_LINEAR:
272 case GL_LINEAR_MIPMAP_LINEAR:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400273 if (restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400274 {
275 // OES_EGL_image_external specifies this error.
Jamie Madille0472f32018-11-27 16:32:45 -0500276 context->validationError(GL_INVALID_ENUM, kInvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400277 return false;
278 }
279 break;
280
281 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500282 context->validationError(GL_INVALID_ENUM, kInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400283 return false;
284 }
285
286 return true;
287}
288
289template <typename ParamType>
290bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
291{
292 switch (ConvertToGLenum(params[0]))
293 {
294 case GL_NEAREST:
295 case GL_LINEAR:
296 break;
297
298 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_ENUM, kInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400300 return false;
301 }
302
303 return true;
304}
305
306template <typename ParamType>
307bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
308{
309 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
310 switch (ConvertToGLenum(params[0]))
311 {
312 case GL_NONE:
313 case GL_COMPARE_REF_TO_TEXTURE:
314 break;
315
316 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500317 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400318 return false;
319 }
320
321 return true;
322}
323
324template <typename ParamType>
325bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
326{
327 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
328 switch (ConvertToGLenum(params[0]))
329 {
330 case GL_LEQUAL:
331 case GL_GEQUAL:
332 case GL_LESS:
333 case GL_GREATER:
334 case GL_EQUAL:
335 case GL_NOTEQUAL:
336 case GL_ALWAYS:
337 case GL_NEVER:
338 break;
339
340 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500341 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400342 return false;
343 }
344
345 return true;
346}
347
348template <typename ParamType>
Geoff Lang81c6b572016-10-19 14:07:52 -0700349bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
350{
351 if (!context->getExtensions().textureSRGBDecode)
352 {
Jamie Madille0472f32018-11-27 16:32:45 -0500353 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang81c6b572016-10-19 14:07:52 -0700354 return false;
355 }
356
357 switch (ConvertToGLenum(params[0]))
358 {
359 case GL_DECODE_EXT:
360 case GL_SKIP_DECODE_EXT:
361 break;
362
363 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500364 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Lang81c6b572016-10-19 14:07:52 -0700365 return false;
366 }
367
368 return true;
369}
370
Luc Ferron1b1a8642018-01-23 15:12:01 -0500371bool ValidateTextureMaxAnisotropyExtensionEnabled(Context *context)
372{
373 if (!context->getExtensions().textureFilterAnisotropic)
374 {
Jamie Madille0472f32018-11-27 16:32:45 -0500375 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500376 return false;
377 }
378
379 return true;
380}
381
382bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
383{
384 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
385 {
386 return false;
387 }
388
389 GLfloat largest = context->getExtensions().maxTextureAnisotropy;
390
391 if (paramValue < 1 || paramValue > largest)
392 {
Jamie Madille0472f32018-11-27 16:32:45 -0500393 context->validationError(GL_INVALID_VALUE, kOutsideOfBounds);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500394 return false;
395 }
396
397 return true;
398}
399
Jamie Madill5b772312018-03-08 20:28:32 -0500400bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
Geoff Lange0cff192017-05-30 13:04:56 -0400401{
Jamie Madill785e8a02018-10-04 17:42:00 -0400402 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lange0cff192017-05-30 13:04:56 -0400403 const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
404
Jamie Madille7d80f32018-08-08 15:49:23 -0400405 return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
406 framebuffer->getDrawBufferTypeMask().to_ulong(),
407 program->getActiveOutputVariables().to_ulong(),
408 framebuffer->getDrawBufferMask().to_ulong());
Geoff Lange0cff192017-05-30 13:04:56 -0400409}
410
Jamie Madill5b772312018-03-08 20:28:32 -0500411bool ValidateVertexShaderAttributeTypeMatch(Context *context)
Geoff Lang9ab5b822017-05-30 16:19:23 -0400412{
Lingfeng Yang038dd532018-03-29 17:31:52 -0700413 const auto &glState = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -0400414 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400415 const VertexArray *vao = context->getGLState().getVertexArray();
416
Brandon Jonesc405ae72017-12-06 14:15:03 -0800417 unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
418 unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
419 unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
420
421 vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
422 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
423 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
424
Jamie Madille7d80f32018-08-08 15:49:23 -0400425 return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
426 vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
427 0xFFFF);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400428}
429
Jamie Madill493f9572018-05-24 19:52:15 -0400430bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
431 PrimitiveMode geometryShaderInputPrimitiveType)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800432{
433 // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
Jamie Madill493f9572018-05-24 19:52:15 -0400434 switch (drawMode)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800435 {
Jamie Madill493f9572018-05-24 19:52:15 -0400436 case PrimitiveMode::Points:
437 return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
438 case PrimitiveMode::Lines:
439 case PrimitiveMode::LineStrip:
440 case PrimitiveMode::LineLoop:
441 return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
442 case PrimitiveMode::LinesAdjacency:
443 case PrimitiveMode::LineStripAdjacency:
444 return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
445 case PrimitiveMode::Triangles:
446 case PrimitiveMode::TriangleFan:
447 case PrimitiveMode::TriangleStrip:
448 return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
449 case PrimitiveMode::TrianglesAdjacency:
450 case PrimitiveMode::TriangleStripAdjacency:
451 return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
Jiawei Shaofccebff2018-03-08 13:51:02 +0800452 default:
453 UNREACHABLE();
454 return false;
455 }
456}
457
Lingfeng Yangf97641c2018-06-21 19:22:45 -0700458// GLES1 texture parameters are a small subset of the others
459bool IsValidGLES1TextureParameter(GLenum pname)
460{
461 switch (pname)
462 {
463 case GL_TEXTURE_MAG_FILTER:
464 case GL_TEXTURE_MIN_FILTER:
465 case GL_TEXTURE_WRAP_S:
466 case GL_TEXTURE_WRAP_T:
467 case GL_TEXTURE_WRAP_R:
468 case GL_GENERATE_MIPMAP:
469 case GL_TEXTURE_CROP_RECT_OES:
470 return true;
471 default:
472 return false;
473 }
474}
Till Rathmannb8543632018-10-02 19:46:14 +0200475
476unsigned int GetSamplerParameterCount(GLenum pname)
477{
478 return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
479}
480
Geoff Langf41a7152016-09-19 15:11:17 -0400481} // anonymous namespace
482
Brandon Jonesd1049182018-03-28 10:02:20 -0700483void SetRobustLengthParam(GLsizei *length, GLsizei value)
484{
485 if (length)
486 {
487 *length = value;
488 }
489}
490
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500491bool IsETC2EACFormat(const GLenum format)
492{
493 // ES 3.1, Table 8.19
494 switch (format)
495 {
496 case GL_COMPRESSED_R11_EAC:
497 case GL_COMPRESSED_SIGNED_R11_EAC:
498 case GL_COMPRESSED_RG11_EAC:
499 case GL_COMPRESSED_SIGNED_RG11_EAC:
500 case GL_COMPRESSED_RGB8_ETC2:
501 case GL_COMPRESSED_SRGB8_ETC2:
502 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
503 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
504 case GL_COMPRESSED_RGBA8_ETC2_EAC:
505 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
506 return true;
507
508 default:
509 return false;
510 }
511}
512
Jamie Madill5b772312018-03-08 20:28:32 -0500513bool ValidTextureTarget(const Context *context, TextureType type)
Jamie Madill35d15012013-10-07 10:46:37 -0400514{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800515 switch (type)
Jamie Madill35d15012013-10-07 10:46:37 -0400516 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800517 case TextureType::_2D:
518 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800519 return true;
Jamie Madill35d15012013-10-07 10:46:37 -0400520
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800521 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400522 return context->getExtensions().textureRectangle;
523
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800524 case TextureType::_3D:
525 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800526 return (context->getClientMajorVersion() >= 3);
Jamie Madilld7460c72014-01-21 16:38:14 -0500527
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800528 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800529 return (context->getClientVersion() >= Version(3, 1) ||
530 context->getExtensions().textureMultisample);
Olli Etuahod310a432018-08-24 15:40:23 +0300531 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300532 return context->getExtensions().textureStorageMultisample2DArray;
Geoff Lang3b573612016-10-31 14:08:10 -0400533
He Yunchaoced53ae2016-11-29 15:00:51 +0800534 default:
535 return false;
Jamie Madilld7460c72014-01-21 16:38:14 -0500536 }
Jamie Madill35d15012013-10-07 10:46:37 -0400537}
538
Jamie Madill5b772312018-03-08 20:28:32 -0500539bool ValidTexture2DTarget(const Context *context, TextureType type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500540{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800541 switch (type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500542 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800543 case TextureType::_2D:
544 case TextureType::CubeMap:
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500545 return true;
546
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800547 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400548 return context->getExtensions().textureRectangle;
549
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500550 default:
551 return false;
552 }
553}
554
Jamie Madill5b772312018-03-08 20:28:32 -0500555bool ValidTexture3DTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500556{
557 switch (target)
558 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800559 case TextureType::_3D:
560 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +0300561 return (context->getClientMajorVersion() >= 3);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500562
563 default:
564 return false;
565 }
566}
567
Ian Ewellbda75592016-04-18 17:25:54 -0400568// Most texture GL calls are not compatible with external textures, so we have a separate validation
569// function for use in the GL calls that do
Jamie Madill5b772312018-03-08 20:28:32 -0500570bool ValidTextureExternalTarget(const Context *context, TextureType target)
Ian Ewellbda75592016-04-18 17:25:54 -0400571{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800572 return (target == TextureType::External) &&
Ian Ewellbda75592016-04-18 17:25:54 -0400573 (context->getExtensions().eglImageExternal ||
574 context->getExtensions().eglStreamConsumerExternal);
575}
576
Shannon Woods4dfed832014-03-17 20:03:39 -0400577// This function differs from ValidTextureTarget in that the target must be
578// usable as the destination of a 2D operation-- so a cube face is valid, but
579// GL_TEXTURE_CUBE_MAP is not.
Jamie Madill560a8d82014-05-21 13:06:20 -0400580// Note: duplicate of IsInternalTextureTarget
Jamie Madill5b772312018-03-08 20:28:32 -0500581bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
Shannon Woods4dfed832014-03-17 20:03:39 -0400582{
583 switch (target)
584 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800585 case TextureTarget::_2D:
586 case TextureTarget::CubeMapNegativeX:
587 case TextureTarget::CubeMapNegativeY:
588 case TextureTarget::CubeMapNegativeZ:
589 case TextureTarget::CubeMapPositiveX:
590 case TextureTarget::CubeMapPositiveY:
591 case TextureTarget::CubeMapPositiveZ:
He Yunchaoced53ae2016-11-29 15:00:51 +0800592 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800593 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400594 return context->getExtensions().textureRectangle;
He Yunchaoced53ae2016-11-29 15:00:51 +0800595 default:
596 return false;
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500597 }
598}
599
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800600bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400601 PrimitiveMode transformFeedbackPrimitiveMode,
602 PrimitiveMode renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800603{
604 ASSERT(context);
605
606 if (!context->getExtensions().geometryShader)
607 {
608 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
609 // that does not match the current transform feedback object's draw mode (if transform
610 // feedback is active), (3.0.2, section 2.14, pg 86)
611 return transformFeedbackPrimitiveMode == renderPrimitiveMode;
612 }
613
614 // [GL_EXT_geometry_shader] Table 12.1gs
Jamie Madill493f9572018-05-24 19:52:15 -0400615 switch (renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800616 {
Jamie Madill493f9572018-05-24 19:52:15 -0400617 case PrimitiveMode::Points:
618 return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
619 case PrimitiveMode::Lines:
620 case PrimitiveMode::LineStrip:
621 case PrimitiveMode::LineLoop:
622 return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
623 case PrimitiveMode::Triangles:
624 case PrimitiveMode::TriangleFan:
625 case PrimitiveMode::TriangleStrip:
626 return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800627 default:
628 UNREACHABLE();
629 return false;
630 }
631}
632
Jamie Madill5b772312018-03-08 20:28:32 -0500633bool ValidateDrawElementsInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400634 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400635 GLsizei count,
636 GLenum type,
637 const GLvoid *indices,
638 GLsizei primcount)
639{
640 if (primcount < 0)
641 {
Jamie Madille0472f32018-11-27 16:32:45 -0500642 context->validationError(GL_INVALID_VALUE, kNegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400643 return false;
644 }
645
646 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount))
647 {
648 return false;
649 }
650
Jamie Madill9fdaa492018-02-16 10:52:11 -0500651 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400652}
653
654bool ValidateDrawArraysInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400655 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400656 GLint first,
657 GLsizei count,
658 GLsizei primcount)
659{
660 if (primcount < 0)
661 {
Jamie Madille0472f32018-11-27 16:32:45 -0500662 context->validationError(GL_INVALID_VALUE, kNegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400663 return false;
664 }
665
666 if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
667 {
668 return false;
669 }
670
Jamie Madill9fdaa492018-02-16 10:52:11 -0500671 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400672}
673
Jamie Madill5b772312018-03-08 20:28:32 -0500674bool ValidateDrawInstancedANGLE(Context *context)
Jamie Madillbe849e42017-05-02 15:49:00 -0400675{
676 // Verify there is at least one active attribute with a divisor of zero
677 const State &state = context->getGLState();
678
Jamie Madill785e8a02018-10-04 17:42:00 -0400679 Program *program = state.getLinkedProgram(context);
Jamie Madillbe849e42017-05-02 15:49:00 -0400680
681 const auto &attribs = state.getVertexArray()->getVertexAttributes();
682 const auto &bindings = state.getVertexArray()->getVertexBindings();
683 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
684 {
685 const VertexAttribute &attrib = attribs[attributeIndex];
686 const VertexBinding &binding = bindings[attrib.bindingIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +0300687 if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400688 {
689 return true;
690 }
691 }
692
Jamie Madille0472f32018-11-27 16:32:45 -0500693 context->validationError(GL_INVALID_OPERATION, kNoZeroDivisor);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695}
696
Jamie Madill5b772312018-03-08 20:28:32 -0500697bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500698{
699 switch (target)
700 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800701 case TextureType::_3D:
702 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800703 return true;
704 default:
705 return false;
Shannon Woods4dfed832014-03-17 20:03:39 -0400706 }
707}
708
Jamie Madill5b772312018-03-08 20:28:32 -0500709bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
He Yunchao11b038b2016-11-22 21:24:04 +0800710{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800711 switch (type)
He Yunchao11b038b2016-11-22 21:24:04 +0800712 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800713 case TextureType::_2D:
714 case TextureType::_2DArray:
715 case TextureType::_2DMultisample:
716 case TextureType::CubeMap:
717 case TextureType::_3D:
He Yunchao11b038b2016-11-22 21:24:04 +0800718 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800719 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400720 return context->getExtensions().textureRectangle;
Olli Etuahod310a432018-08-24 15:40:23 +0300721 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300722 return context->getExtensions().textureStorageMultisample2DArray;
He Yunchao11b038b2016-11-22 21:24:04 +0800723 default:
724 return false;
725 }
726}
727
Jamie Madill5b772312018-03-08 20:28:32 -0500728bool ValidFramebufferTarget(const Context *context, GLenum target)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500729{
He Yunchaoced53ae2016-11-29 15:00:51 +0800730 static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
731 GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
Geoff Langd4475812015-03-18 10:53:05 -0400732 "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500733
734 switch (target)
735 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800736 case GL_FRAMEBUFFER:
737 return true;
Geoff Lange8afa902017-09-27 15:00:43 -0400738
He Yunchaoced53ae2016-11-29 15:00:51 +0800739 case GL_READ_FRAMEBUFFER:
He Yunchaoced53ae2016-11-29 15:00:51 +0800740 case GL_DRAW_FRAMEBUFFER:
Geoff Lange8afa902017-09-27 15:00:43 -0400741 return (context->getExtensions().framebufferBlit ||
742 context->getClientMajorVersion() >= 3);
743
He Yunchaoced53ae2016-11-29 15:00:51 +0800744 default:
745 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500746 }
747}
748
Jamie Madill5b772312018-03-08 20:28:32 -0500749bool ValidMipLevel(const Context *context, TextureType type, GLint level)
Geoff Langce635692013-09-24 13:56:32 -0400750{
Jamie Madillc29968b2016-01-20 11:17:23 -0500751 const auto &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -0400752 size_t maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800753 switch (type)
Geoff Langce635692013-09-24 13:56:32 -0400754 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800755 case TextureType::_2D:
756 case TextureType::_2DArray:
757 case TextureType::_2DMultisample:
Olli Etuahod310a432018-08-24 15:40:23 +0300758 case TextureType::_2DMultisampleArray:
759 // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
760 // level-of-detail" for multisample textures should be. Could maybe make it zero.
Jamie Madillc29968b2016-01-20 11:17:23 -0500761 maxDimension = caps.max2DTextureSize;
762 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800763 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800764 maxDimension = caps.maxCubeMapTextureSize;
765 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800766 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400767 return level == 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800768 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800769 maxDimension = caps.max3DTextureSize;
770 break;
He Yunchaoced53ae2016-11-29 15:00:51 +0800771 default:
772 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400773 }
774
Jamie Madill43da7c42018-08-01 11:34:49 -0400775 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400776}
777
Jamie Madill5b772312018-03-08 20:28:32 -0500778bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800779 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700780 GLint level,
781 GLsizei width,
782 GLsizei height,
783 GLsizei depth,
784 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400785{
Brandon Jones6cad5662017-06-14 13:25:13 -0700786 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400787 {
Jamie Madille0472f32018-11-27 16:32:45 -0500788 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400789 return false;
790 }
Austin Kinross08528e12015-10-07 16:24:40 -0700791 // TexSubImage parameters can be NPOT without textureNPOT extension,
792 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500793 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500794 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500795 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400796 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400797 {
Jamie Madille0472f32018-11-27 16:32:45 -0500798 context->validationError(GL_INVALID_VALUE, kTextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400799 return false;
800 }
801
802 if (!ValidMipLevel(context, target, level))
803 {
Jamie Madille0472f32018-11-27 16:32:45 -0500804 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400805 return false;
806 }
807
808 return true;
809}
810
Geoff Lang966c9402017-04-18 12:38:27 -0400811bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
812{
813 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
814 (size % blockSize == 0);
815}
816
Jamie Madill5b772312018-03-08 20:28:32 -0500817bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500818 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400819 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500820 GLsizei width,
821 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400822{
Jamie Madill43da7c42018-08-01 11:34:49 -0400823 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400824 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400825 {
826 return false;
827 }
828
Geoff Lang966c9402017-04-18 12:38:27 -0400829 if (width < 0 || height < 0)
830 {
831 return false;
832 }
833
834 if (CompressedTextureFormatRequiresExactSize(internalFormat))
835 {
836 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
837 // block size for level 0 but WebGL disallows this.
838 bool smallerThanBlockSizeAllowed =
839 level > 0 || !context->getExtensions().webglCompatibility;
840
841 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
842 smallerThanBlockSizeAllowed) ||
843 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
844 smallerThanBlockSizeAllowed))
845 {
846 return false;
847 }
848 }
849
850 return true;
851}
852
Jamie Madill5b772312018-03-08 20:28:32 -0500853bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400854 GLenum internalFormat,
855 GLint xoffset,
856 GLint yoffset,
857 GLsizei width,
858 GLsizei height,
859 size_t textureWidth,
860 size_t textureHeight)
861{
Jamie Madill43da7c42018-08-01 11:34:49 -0400862 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400863 if (!formatInfo.compressed)
864 {
865 return false;
866 }
867
Geoff Lang44ff5a72017-02-03 15:15:43 -0500868 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400869 {
870 return false;
871 }
872
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500873 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400874 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500875 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400876 yoffset % formatInfo.compressedBlockHeight != 0)
877 {
878 return false;
879 }
880
881 // Allowed to either have data that is a multiple of block size or is smaller than the block
882 // size but fills the entire mip
883 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
884 static_cast<size_t>(width) == textureWidth &&
885 static_cast<size_t>(height) == textureHeight;
886 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
887 (height % formatInfo.compressedBlockHeight) == 0;
888 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400889 {
890 return false;
891 }
892 }
893
Geoff Langd4f180b2013-09-24 13:57:44 -0400894 return true;
895}
896
Jamie Madill5b772312018-03-08 20:28:32 -0500897bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800898 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400899 GLsizei width,
900 GLsizei height,
901 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400902 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400903 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400904 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400905 GLsizei imageSize)
906{
Jamie Madill43da7c42018-08-01 11:34:49 -0400907 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400908 if (pixelUnpackBuffer == nullptr && imageSize < 0)
909 {
910 // Checks are not required
911 return true;
912 }
913
914 // ...the data would be unpacked from the buffer object such that the memory reads required
915 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400916 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400917 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400918 const Extents size(width, height, depth);
Geoff Langff5b2d52016-09-07 11:32:23 -0400919 const auto &unpack = context->getGLState().getUnpackState();
920
Jamie Madill7f232932018-09-12 11:03:06 -0400921 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
922 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400923 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400924 {
Jamie Madille0472f32018-11-27 16:32:45 -0500925 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400926 return false;
927 }
928
Geoff Langff5b2d52016-09-07 11:32:23 -0400929 if (pixelUnpackBuffer)
930 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400931 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400932 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
933 checkedEndByte += checkedOffset;
934
935 if (!checkedEndByte.IsValid() ||
936 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
937 {
938 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -0500939 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400940 return false;
941 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800942 if (context->getExtensions().webglCompatibility &&
943 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
944 {
Jamie Madill610640f2018-11-21 17:28:41 -0500945 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -0500946 kPixelUnpackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -0800947 return false;
948 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400949 }
950 else
951 {
952 ASSERT(imageSize >= 0);
953 if (pixels == nullptr && imageSize != 0)
954 {
Jamie Madill610640f2018-11-21 17:28:41 -0500955 context->validationError(GL_INVALID_OPERATION,
956 "imageSize must be 0 if no texture data is provided.");
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400957 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400958 }
959
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400960 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400961 {
Jamie Madill610640f2018-11-21 17:28:41 -0500962 context->validationError(GL_INVALID_OPERATION, "imageSize is too small");
Geoff Langff5b2d52016-09-07 11:32:23 -0400963 return false;
964 }
965 }
966
967 return true;
968}
969
Corentin Wallezad3ae902018-03-09 13:40:42 -0500970bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500971{
Geoff Lang37dde692014-01-31 16:34:54 -0500972 switch (queryType)
973 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500974 case QueryType::AnySamples:
975 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400976 return context->getClientMajorVersion() >= 3 ||
977 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500978 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800979 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500980 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800981 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500982 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800983 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500984 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800985 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800986 default:
987 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500988 }
989}
990
Jamie Madill5b772312018-03-08 20:28:32 -0500991bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400992 GLenum type,
993 GLboolean normalized,
994 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400995 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400996 bool pureInteger)
997{
998 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -0400999 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
1000 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
1001 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
1002 // parameter exceeds 255.
1003 constexpr GLsizei kMaxWebGLStride = 255;
1004 if (stride > kMaxWebGLStride)
1005 {
Jamie Madill610640f2018-11-21 17:28:41 -05001006 context->validationError(GL_INVALID_VALUE,
1007 "Stride is over the maximum stride allowed by WebGL.");
Geoff Lang2d62ab72017-03-23 16:54:40 -04001008 return false;
1009 }
1010
1011 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1012 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1013 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1014 // or an INVALID_OPERATION error is generated.
Frank Henigmand633b152018-10-04 23:34:31 -04001015 angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1016 size_t typeSize = GetVertexFormatSize(internalType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001017
1018 ASSERT(isPow2(typeSize) && typeSize > 0);
1019 size_t sizeMask = (typeSize - 1);
1020 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1021 {
Jamie Madille0472f32018-11-27 16:32:45 -05001022 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001023 return false;
1024 }
1025
1026 if ((stride & sizeMask) != 0)
1027 {
Jamie Madille0472f32018-11-27 16:32:45 -05001028 context->validationError(GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001029 return false;
1030 }
1031
1032 return true;
1033}
1034
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001035Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001036{
He Yunchaoced53ae2016-11-29 15:00:51 +08001037 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1038 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1039 // or program object and INVALID_OPERATION if the provided name identifies an object
1040 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001041
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001042 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001043
1044 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001045 {
Dian Xiang769769a2015-09-09 15:20:08 -07001046 if (context->getShader(id))
1047 {
Jamie Madille0472f32018-11-27 16:32:45 -05001048 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001049 }
1050 else
1051 {
Jamie Madille0472f32018-11-27 16:32:45 -05001052 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001053 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001054 }
Dian Xiang769769a2015-09-09 15:20:08 -07001055
1056 return validProgram;
1057}
1058
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001059Program *GetValidProgram(Context *context, GLuint id)
1060{
1061 Program *program = GetValidProgramNoResolve(context, id);
1062 if (program)
1063 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001064 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001065 }
1066 return program;
1067}
1068
Jamie Madill5b772312018-03-08 20:28:32 -05001069Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001070{
1071 // See ValidProgram for spec details.
1072
1073 Shader *validShader = context->getShader(id);
1074
1075 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001076 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001077 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001078 {
Jamie Madille0472f32018-11-27 16:32:45 -05001079 context->validationError(GL_INVALID_OPERATION, kExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001080 }
1081 else
1082 {
Jamie Madille0472f32018-11-27 16:32:45 -05001083 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001084 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001085 }
Dian Xiang769769a2015-09-09 15:20:08 -07001086
1087 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001088}
1089
Jamie Madill43da7c42018-08-01 11:34:49 -04001090bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001091{
Geoff Langfa125c92017-10-24 13:01:46 -04001092 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001093 {
Geoff Langfa125c92017-10-24 13:01:46 -04001094 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1095 {
Jamie Madille0472f32018-11-27 16:32:45 -05001096 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langfa125c92017-10-24 13:01:46 -04001097 return false;
1098 }
Jamie Madillb4472272014-07-03 10:38:55 -04001099
Geoff Langfa125c92017-10-24 13:01:46 -04001100 // Color attachment 0 is validated below because it is always valid
1101 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001102 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001103 {
Jamie Madille0472f32018-11-27 16:32:45 -05001104 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001105 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001106 }
1107 }
1108 else
1109 {
1110 switch (attachment)
1111 {
Geoff Langfa125c92017-10-24 13:01:46 -04001112 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001113 case GL_DEPTH_ATTACHMENT:
1114 case GL_STENCIL_ATTACHMENT:
1115 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001116
He Yunchaoced53ae2016-11-29 15:00:51 +08001117 case GL_DEPTH_STENCIL_ATTACHMENT:
1118 if (!context->getExtensions().webglCompatibility &&
1119 context->getClientMajorVersion() < 3)
1120 {
Jamie Madille0472f32018-11-27 16:32:45 -05001121 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001122 return false;
1123 }
1124 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001125
He Yunchaoced53ae2016-11-29 15:00:51 +08001126 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001127 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001128 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001129 }
1130 }
1131
1132 return true;
1133}
1134
Jamie Madill5b772312018-03-08 20:28:32 -05001135bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001136 GLenum target,
1137 GLsizei samples,
1138 GLenum internalformat,
1139 GLsizei width,
1140 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001141{
1142 switch (target)
1143 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001144 case GL_RENDERBUFFER:
1145 break;
1146 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001148 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001149 }
1150
1151 if (width < 0 || height < 0 || samples < 0)
1152 {
Jamie Madille0472f32018-11-27 16:32:45 -05001153 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001154 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001155 }
1156
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001157 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1158 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1159
1160 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001161 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001162 {
Jamie Madille0472f32018-11-27 16:32:45 -05001163 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001164 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 }
1166
1167 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1168 // sized but it does state that the format must be in the ES2.0 spec table 4.5 which contains
Corentin Walleze0902642014-11-04 12:32:15 -08001169 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001170 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001171 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001172 {
Jamie Madille0472f32018-11-27 16:32:45 -05001173 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001174 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 }
1176
Geoff Langaae65a42014-05-26 12:43:44 -04001177 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001178 {
Jamie Madille0472f32018-11-27 16:32:45 -05001179 context->validationError(GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04001180 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 }
1182
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001183 GLuint handle = context->getGLState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 if (handle == 0)
1185 {
Jamie Madille0472f32018-11-27 16:32:45 -05001186 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001187 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001188 }
1189
1190 return true;
1191}
1192
Jamie Madill43da7c42018-08-01 11:34:49 -04001193bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 GLenum target,
1195 GLenum attachment,
1196 GLenum renderbuffertarget,
1197 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001198{
Geoff Lange8afa902017-09-27 15:00:43 -04001199 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001200 {
Jamie Madille0472f32018-11-27 16:32:45 -05001201 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001202 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001203 }
1204
Jamie Madill43da7c42018-08-01 11:34:49 -04001205 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001206
Jamie Madill84115c92015-04-23 15:00:07 -04001207 ASSERT(framebuffer);
1208 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209 {
Jamie Madille0472f32018-11-27 16:32:45 -05001210 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001212 }
1213
Jamie Madillb4472272014-07-03 10:38:55 -04001214 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001215 {
Jamie Madillb4472272014-07-03 10:38:55 -04001216 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001217 }
1218
Jamie Madillab9d82c2014-01-21 16:38:14 -05001219 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1220 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1221 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1222 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1223 if (renderbuffer != 0)
1224 {
1225 if (!context->getRenderbuffer(renderbuffer))
1226 {
Jamie Madille0472f32018-11-27 16:32:45 -05001227 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001228 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001229 }
1230 }
1231
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001232 return true;
1233}
1234
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001235bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001236 GLint srcX0,
1237 GLint srcY0,
1238 GLint srcX1,
1239 GLint srcY1,
1240 GLint dstX0,
1241 GLint dstY0,
1242 GLint dstX1,
1243 GLint dstY1,
1244 GLbitfield mask,
1245 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001246{
1247 switch (filter)
1248 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001249 case GL_NEAREST:
1250 break;
1251 case GL_LINEAR:
1252 break;
1253 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001254 context->validationError(GL_INVALID_ENUM, kBlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001255 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001256 }
1257
1258 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1259 {
Jamie Madille0472f32018-11-27 16:32:45 -05001260 context->validationError(GL_INVALID_VALUE, kBlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001261 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 }
1263
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001264 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1265 // color buffer, leaving only nearest being unfiltered from above
1266 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1267 {
Jamie Madille0472f32018-11-27 16:32:45 -05001268 context->validationError(GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001269 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001270 }
1271
Jamie Madill7f232932018-09-12 11:03:06 -04001272 const auto &glState = context->getGLState();
1273 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1274 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001275
1276 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001277 {
Jamie Madille0472f32018-11-27 16:32:45 -05001278 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001279 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001280 }
1281
Jamie Madill427064d2018-04-13 16:20:34 -04001282 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001283 {
Jamie Madill48faf802014-11-06 15:27:22 -05001284 return false;
1285 }
1286
Jamie Madill427064d2018-04-13 16:20:34 -04001287 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001288 {
Jamie Madill48faf802014-11-06 15:27:22 -05001289 return false;
1290 }
1291
Qin Jiajiaaef92162018-02-27 13:51:44 +08001292 if (readFramebuffer->id() == drawFramebuffer->id())
1293 {
Jamie Madille0472f32018-11-27 16:32:45 -05001294 context->validationError(GL_INVALID_OPERATION, kBlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001295 return false;
1296 }
1297
Jamie Madille98b1b52018-03-08 09:47:23 -05001298 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001299 {
Geoff Langb1196682014-07-23 13:47:29 -04001300 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001301 }
1302
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001303 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1304 // always run it in order to avoid triggering driver bugs.
1305 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1306 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001307 {
Jamie Madille0472f32018-11-27 16:32:45 -05001308 context->validationError(GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001309 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001310 }
1311
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001312 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1313
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001314 if (mask & GL_COLOR_BUFFER_BIT)
1315 {
Jamie Madill7f232932018-09-12 11:03:06 -04001316 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1317 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001318
He Yunchao66a41a22016-12-15 16:45:05 +08001319 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001320 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001321 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001322
Geoff Langa15472a2015-08-11 11:48:03 -04001323 for (size_t drawbufferIdx = 0;
1324 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001325 {
Geoff Langa15472a2015-08-11 11:48:03 -04001326 const FramebufferAttachment *attachment =
1327 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1328 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001330 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001331
Geoff Langb2f3d052013-08-13 12:49:27 -04001332 // The GL ES 3.0.2 spec (pg 193) states that:
1333 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1335 // as well
1336 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1337 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001338 // Changes with EXT_color_buffer_float:
1339 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001340 GLenum readComponentType = readFormat.info->componentType;
1341 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001342 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001343 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001344 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001345 drawComponentType == GL_SIGNED_NORMALIZED);
1346
1347 if (extensions.colorBufferFloat)
1348 {
1349 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1350 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1351
1352 if (readFixedOrFloat != drawFixedOrFloat)
1353 {
Jamie Madill610640f2018-11-21 17:28:41 -05001354 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001355 kBlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001356 return false;
1357 }
1358 }
1359 else if (readFixedPoint != drawFixedPoint)
1360 {
Jamie Madille0472f32018-11-27 16:32:45 -05001361 context->validationError(GL_INVALID_OPERATION, kBlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001362 return false;
1363 }
1364
1365 if (readComponentType == GL_UNSIGNED_INT &&
1366 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001367 {
Jamie Madill610640f2018-11-21 17:28:41 -05001368 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001369 kBlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001370 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001371 }
1372
Jamie Madill6163c752015-12-07 16:32:59 -05001373 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 {
Jamie Madill610640f2018-11-21 17:28:41 -05001375 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001376 kBlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001377 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001378 }
1379
Jamie Madilla3944d42016-07-22 22:13:26 -04001380 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001381 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001382 {
Jamie Madill610640f2018-11-21 17:28:41 -05001383 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001384 kBlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001385 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001386 }
Geoff Lange4915782017-04-12 15:19:07 -04001387
1388 if (context->getExtensions().webglCompatibility &&
1389 *readColorBuffer == *attachment)
1390 {
Jamie Madille0472f32018-11-27 16:32:45 -05001391 context->validationError(GL_INVALID_OPERATION, kBlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001392 return false;
1393 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001394 }
1395 }
1396
Jamie Madilla3944d42016-07-22 22:13:26 -04001397 if ((readFormat.info->componentType == GL_INT ||
1398 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1399 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001400 {
Jamie Madille0472f32018-11-27 16:32:45 -05001401 context->validationError(GL_INVALID_OPERATION, kBlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001402 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001403 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001404 }
He Yunchao66a41a22016-12-15 16:45:05 +08001405 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1406 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1407 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1408 // situation is an application error that would lead to a crash in ANGLE.
1409 else if (drawFramebuffer->hasEnabledDrawBuffer())
1410 {
Jamie Madille0472f32018-11-27 16:32:45 -05001411 context->validationError(GL_INVALID_OPERATION, kBlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001412 return false;
1413 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001414 }
1415
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001417 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1418 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001419 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001420 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001422 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001423 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001424 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001425 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001426
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001427 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001428 {
Kenneth Russell69382852017-07-21 16:38:44 -04001429 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001430 {
Jamie Madill610640f2018-11-21 17:28:41 -05001431 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001432 kBlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001433 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001434 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001435
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001436 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001437 {
Jamie Madille0472f32018-11-27 16:32:45 -05001438 context->validationError(GL_INVALID_OPERATION, kBlitMultisampledBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001439 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001440 }
Geoff Lange4915782017-04-12 15:19:07 -04001441
1442 if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer)
1443 {
Jamie Madille0472f32018-11-27 16:32:45 -05001444 context->validationError(GL_INVALID_OPERATION, kBlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001445 return false;
1446 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001447 }
He Yunchao66a41a22016-12-15 16:45:05 +08001448 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1449 else if (drawBuffer)
1450 {
Jamie Madille0472f32018-11-27 16:32:45 -05001451 context->validationError(GL_INVALID_OPERATION, kBlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001452 return false;
1453 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001454 }
1455 }
1456
Martin Radeva3ed4572017-07-27 18:29:37 +03001457 // ANGLE_multiview, Revision 1:
1458 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001459 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1460 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1461 // views in the current read framebuffer is more than one.
1462 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001463 {
Jamie Madille0472f32018-11-27 16:32:45 -05001464 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001465 return false;
1466 }
1467 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1468 {
Jamie Madille0472f32018-11-27 16:32:45 -05001469 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001470 return false;
1471 }
1472
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001473 return true;
1474}
1475
Jamie Madill4928b7c2017-06-20 12:57:39 -04001476bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001477 GLint x,
1478 GLint y,
1479 GLsizei width,
1480 GLsizei height,
1481 GLenum format,
1482 GLenum type,
1483 GLsizei bufSize,
1484 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001485 GLsizei *columns,
1486 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001487 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001488{
1489 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001490 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001491 return false;
1492 }
1493
Brandon Jonesd1049182018-03-28 10:02:20 -07001494 GLsizei writeLength = 0;
1495 GLsizei writeColumns = 0;
1496 GLsizei writeRows = 0;
1497
1498 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1499 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001500 {
Geoff Langb1196682014-07-23 13:47:29 -04001501 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001502 }
1503
Brandon Jonesd1049182018-03-28 10:02:20 -07001504 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001505 {
Geoff Langb1196682014-07-23 13:47:29 -04001506 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001507 }
1508
Brandon Jonesd1049182018-03-28 10:02:20 -07001509 SetRobustLengthParam(length, writeLength);
1510 SetRobustLengthParam(columns, writeColumns);
1511 SetRobustLengthParam(rows, writeRows);
1512
Jamie Madillc29968b2016-01-20 11:17:23 -05001513 return true;
1514}
1515
1516bool ValidateReadnPixelsEXT(Context *context,
1517 GLint x,
1518 GLint y,
1519 GLsizei width,
1520 GLsizei height,
1521 GLenum format,
1522 GLenum type,
1523 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001524 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001525{
1526 if (bufSize < 0)
1527 {
Jamie Madille0472f32018-11-27 16:32:45 -05001528 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001529 return false;
1530 }
1531
Geoff Lang62fce5b2016-09-30 10:46:35 -04001532 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001533 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001534}
Jamie Madill26e91952014-03-05 15:01:27 -05001535
Jamie Madill4928b7c2017-06-20 12:57:39 -04001536bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001537 GLint x,
1538 GLint y,
1539 GLsizei width,
1540 GLsizei height,
1541 GLenum format,
1542 GLenum type,
1543 GLsizei bufSize,
1544 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001545 GLsizei *columns,
1546 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001547 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001548{
Brandon Jonesd1049182018-03-28 10:02:20 -07001549 GLsizei writeLength = 0;
1550 GLsizei writeColumns = 0;
1551 GLsizei writeRows = 0;
1552
Geoff Lang62fce5b2016-09-30 10:46:35 -04001553 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001554 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001555 return false;
1556 }
1557
Brandon Jonesd1049182018-03-28 10:02:20 -07001558 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1559 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001560 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001561 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001562 }
1563
Brandon Jonesd1049182018-03-28 10:02:20 -07001564 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001565 {
1566 return false;
1567 }
1568
Brandon Jonesd1049182018-03-28 10:02:20 -07001569 SetRobustLengthParam(length, writeLength);
1570 SetRobustLengthParam(columns, writeColumns);
1571 SetRobustLengthParam(rows, writeRows);
1572
Geoff Lang62fce5b2016-09-30 10:46:35 -04001573 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001574}
1575
Jamie Madill43da7c42018-08-01 11:34:49 -04001576bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001577{
1578 if (!context->getExtensions().occlusionQueryBoolean &&
1579 !context->getExtensions().disjointTimerQuery)
1580 {
Jamie Madille0472f32018-11-27 16:32:45 -05001581 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001582 return false;
1583 }
1584
Olli Etuaho41997e72016-03-10 13:38:39 +02001585 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001586}
1587
Jamie Madill43da7c42018-08-01 11:34:49 -04001588bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001589{
1590 if (!context->getExtensions().occlusionQueryBoolean &&
1591 !context->getExtensions().disjointTimerQuery)
1592 {
Jamie Madille0472f32018-11-27 16:32:45 -05001593 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001594 return false;
1595 }
1596
Olli Etuaho41997e72016-03-10 13:38:39 +02001597 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001598}
1599
Jamie Madill43da7c42018-08-01 11:34:49 -04001600bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001601{
1602 if (!context->getExtensions().occlusionQueryBoolean &&
1603 !context->getExtensions().disjointTimerQuery)
1604 {
Jamie Madille0472f32018-11-27 16:32:45 -05001605 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Jamie Madillf0e04492017-08-26 15:28:42 -04001606 return false;
1607 }
1608
1609 return true;
1610}
1611
Jamie Madill43da7c42018-08-01 11:34:49 -04001612bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001613{
1614 if (!ValidQueryType(context, target))
1615 {
Jamie Madille0472f32018-11-27 16:32:45 -05001616 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001617 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001618 }
1619
1620 if (id == 0)
1621 {
Jamie Madill610640f2018-11-21 17:28:41 -05001622 context->validationError(GL_INVALID_OPERATION, "Query id is 0");
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001624 }
1625
1626 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1627 // of zero, if the active query object name for <target> is non-zero (for the
1628 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1629 // the active query for either target is non-zero), if <id> is the name of an
1630 // existing query object whose type does not match <target>, or if <id> is the
1631 // active query object name for any query type, the error INVALID_OPERATION is
1632 // generated.
1633
1634 // Ensure no other queries are active
1635 // NOTE: If other queries than occlusion are supported, we will need to check
1636 // separately that:
1637 // a) The query ID passed is not the current active query for any target/type
1638 // b) There are no active queries for the requested target (and in the case
1639 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1640 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001641
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001642 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001643 {
Jamie Madill610640f2018-11-21 17:28:41 -05001644 context->validationError(GL_INVALID_OPERATION, "Other query is active");
Geoff Langb1196682014-07-23 13:47:29 -04001645 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001646 }
1647
1648 Query *queryObject = context->getQuery(id, true, target);
1649
1650 // check that name was obtained with glGenQueries
1651 if (!queryObject)
1652 {
Jamie Madille0472f32018-11-27 16:32:45 -05001653 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001654 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001655 }
1656
1657 // check for type mismatch
1658 if (queryObject->getType() != target)
1659 {
Jamie Madill610640f2018-11-21 17:28:41 -05001660 context->validationError(GL_INVALID_OPERATION, "Query type does not match target");
Geoff Langb1196682014-07-23 13:47:29 -04001661 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001662 }
1663
1664 return true;
1665}
1666
Jamie Madill43da7c42018-08-01 11:34:49 -04001667bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001668{
1669 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001670 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001671 {
Jamie Madille0472f32018-11-27 16:32:45 -05001672 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001673 return false;
1674 }
1675
1676 return ValidateBeginQueryBase(context, target, id);
1677}
1678
Jamie Madill43da7c42018-08-01 11:34:49 -04001679bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001680{
1681 if (!ValidQueryType(context, target))
1682 {
Jamie Madille0472f32018-11-27 16:32:45 -05001683 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001685 }
1686
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001687 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001688
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001689 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001690 {
Jamie Madill610640f2018-11-21 17:28:41 -05001691 context->validationError(GL_INVALID_OPERATION, "Query target not active");
Geoff Langb1196682014-07-23 13:47:29 -04001692 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001693 }
1694
Jamie Madill45c785d2014-05-13 14:09:34 -04001695 return true;
1696}
1697
Jamie Madill43da7c42018-08-01 11:34:49 -04001698bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001699{
1700 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001701 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001702 {
Jamie Madille0472f32018-11-27 16:32:45 -05001703 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001704 return false;
1705 }
1706
1707 return ValidateEndQueryBase(context, target);
1708}
1709
Corentin Wallezad3ae902018-03-09 13:40:42 -05001710bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001711{
1712 if (!context->getExtensions().disjointTimerQuery)
1713 {
Jamie Madill610640f2018-11-21 17:28:41 -05001714 context->validationError(GL_INVALID_OPERATION, "Disjoint timer query not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001715 return false;
1716 }
1717
Corentin Wallezad3ae902018-03-09 13:40:42 -05001718 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001719 {
Jamie Madille0472f32018-11-27 16:32:45 -05001720 context->validationError(GL_INVALID_ENUM, kInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001721 return false;
1722 }
1723
1724 Query *queryObject = context->getQuery(id, true, target);
1725 if (queryObject == nullptr)
1726 {
Jamie Madille0472f32018-11-27 16:32:45 -05001727 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001728 return false;
1729 }
1730
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001731 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001732 {
Jamie Madille0472f32018-11-27 16:32:45 -05001733 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001734 return false;
1735 }
1736
1737 return true;
1738}
1739
Corentin Wallezad3ae902018-03-09 13:40:42 -05001740bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001741{
Geoff Lang2186c382016-10-14 10:54:54 -04001742 if (numParams)
1743 {
1744 *numParams = 0;
1745 }
1746
Corentin Wallezad3ae902018-03-09 13:40:42 -05001747 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001748 {
Jamie Madille0472f32018-11-27 16:32:45 -05001749 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001750 return false;
1751 }
1752
1753 switch (pname)
1754 {
1755 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001756 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001757 {
Jamie Madill610640f2018-11-21 17:28:41 -05001758 context->validationError(GL_INVALID_ENUM, "Cannot use current query for timestamp");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001759 return false;
1760 }
1761 break;
1762 case GL_QUERY_COUNTER_BITS_EXT:
1763 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001764 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001765 {
Jamie Madille0472f32018-11-27 16:32:45 -05001766 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001767 return false;
1768 }
1769 break;
1770 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001771 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001772 return false;
1773 }
1774
Geoff Lang2186c382016-10-14 10:54:54 -04001775 if (numParams)
1776 {
1777 // All queries return only one value
1778 *numParams = 1;
1779 }
1780
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001781 return true;
1782}
1783
Corentin Wallezad3ae902018-03-09 13:40:42 -05001784bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001785{
1786 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001787 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001788 {
Jamie Madille0472f32018-11-27 16:32:45 -05001789 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001790 return false;
1791 }
1792
Geoff Lang2186c382016-10-14 10:54:54 -04001793 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001794}
1795
Geoff Lang2186c382016-10-14 10:54:54 -04001796bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001797 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001798 GLenum pname,
1799 GLsizei bufSize,
1800 GLsizei *length,
1801 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001802{
Geoff Lang2186c382016-10-14 10:54:54 -04001803 if (!ValidateRobustEntryPoint(context, bufSize))
1804 {
1805 return false;
1806 }
1807
Brandon Jonesd1049182018-03-28 10:02:20 -07001808 GLsizei numParams = 0;
1809
1810 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001811 {
1812 return false;
1813 }
1814
Brandon Jonesd1049182018-03-28 10:02:20 -07001815 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001816 {
1817 return false;
1818 }
1819
Brandon Jonesd1049182018-03-28 10:02:20 -07001820 SetRobustLengthParam(length, numParams);
1821
Geoff Lang2186c382016-10-14 10:54:54 -04001822 return true;
1823}
1824
1825bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1826{
1827 if (numParams)
1828 {
1829 *numParams = 0;
1830 }
1831
Corentin Wallezad3ae902018-03-09 13:40:42 -05001832 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001833
1834 if (!queryObject)
1835 {
Jamie Madille0472f32018-11-27 16:32:45 -05001836 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001837 return false;
1838 }
1839
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001840 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001841 {
Jamie Madille0472f32018-11-27 16:32:45 -05001842 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001843 return false;
1844 }
1845
1846 switch (pname)
1847 {
1848 case GL_QUERY_RESULT_EXT:
1849 case GL_QUERY_RESULT_AVAILABLE_EXT:
1850 break;
1851
1852 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001853 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001854 return false;
1855 }
1856
Geoff Lang2186c382016-10-14 10:54:54 -04001857 if (numParams)
1858 {
1859 *numParams = 1;
1860 }
1861
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001862 return true;
1863}
1864
1865bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1866{
1867 if (!context->getExtensions().disjointTimerQuery)
1868 {
Jamie Madill610640f2018-11-21 17:28:41 -05001869 context->validationError(GL_INVALID_OPERATION, "Timer query extension not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001870 return false;
1871 }
Geoff Lang2186c382016-10-14 10:54:54 -04001872 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1873}
1874
1875bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1876 GLuint id,
1877 GLenum pname,
1878 GLsizei bufSize,
1879 GLsizei *length,
1880 GLint *params)
1881{
1882 if (!context->getExtensions().disjointTimerQuery)
1883 {
Jamie Madill610640f2018-11-21 17:28:41 -05001884 context->validationError(GL_INVALID_OPERATION, "Timer query extension not enabled");
Geoff Lang2186c382016-10-14 10:54:54 -04001885 return false;
1886 }
1887
1888 if (!ValidateRobustEntryPoint(context, bufSize))
1889 {
1890 return false;
1891 }
1892
Brandon Jonesd1049182018-03-28 10:02:20 -07001893 GLsizei numParams = 0;
1894
1895 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001896 {
1897 return false;
1898 }
1899
Brandon Jonesd1049182018-03-28 10:02:20 -07001900 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001901 {
1902 return false;
1903 }
1904
Brandon Jonesd1049182018-03-28 10:02:20 -07001905 SetRobustLengthParam(length, numParams);
1906
Geoff Lang2186c382016-10-14 10:54:54 -04001907 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001908}
1909
1910bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1911{
1912 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001913 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001914 {
Jamie Madille0472f32018-11-27 16:32:45 -05001915 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001916 return false;
1917 }
Geoff Lang2186c382016-10-14 10:54:54 -04001918 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1919}
1920
1921bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1922 GLuint id,
1923 GLenum pname,
1924 GLsizei bufSize,
1925 GLsizei *length,
1926 GLuint *params)
1927{
1928 if (!context->getExtensions().disjointTimerQuery &&
1929 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1930 {
Jamie Madille0472f32018-11-27 16:32:45 -05001931 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001932 return false;
1933 }
1934
1935 if (!ValidateRobustEntryPoint(context, bufSize))
1936 {
1937 return false;
1938 }
1939
Brandon Jonesd1049182018-03-28 10:02:20 -07001940 GLsizei numParams = 0;
1941
1942 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001943 {
1944 return false;
1945 }
1946
Brandon Jonesd1049182018-03-28 10:02:20 -07001947 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001948 {
1949 return false;
1950 }
1951
Brandon Jonesd1049182018-03-28 10:02:20 -07001952 SetRobustLengthParam(length, numParams);
1953
Geoff Lang2186c382016-10-14 10:54:54 -04001954 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001955}
1956
1957bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1958{
1959 if (!context->getExtensions().disjointTimerQuery)
1960 {
Jamie Madille0472f32018-11-27 16:32:45 -05001961 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001962 return false;
1963 }
Geoff Lang2186c382016-10-14 10:54:54 -04001964 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1965}
1966
1967bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1968 GLuint id,
1969 GLenum pname,
1970 GLsizei bufSize,
1971 GLsizei *length,
1972 GLint64 *params)
1973{
1974 if (!context->getExtensions().disjointTimerQuery)
1975 {
Jamie Madille0472f32018-11-27 16:32:45 -05001976 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001977 return false;
1978 }
1979
1980 if (!ValidateRobustEntryPoint(context, bufSize))
1981 {
1982 return false;
1983 }
1984
Brandon Jonesd1049182018-03-28 10:02:20 -07001985 GLsizei numParams = 0;
1986
1987 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001988 {
1989 return false;
1990 }
1991
Brandon Jonesd1049182018-03-28 10:02:20 -07001992 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001993 {
1994 return false;
1995 }
1996
Brandon Jonesd1049182018-03-28 10:02:20 -07001997 SetRobustLengthParam(length, numParams);
1998
Geoff Lang2186c382016-10-14 10:54:54 -04001999 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002000}
2001
2002bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
2003{
2004 if (!context->getExtensions().disjointTimerQuery)
2005 {
Jamie Madille0472f32018-11-27 16:32:45 -05002006 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002007 return false;
2008 }
Geoff Lang2186c382016-10-14 10:54:54 -04002009 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
2010}
2011
2012bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
2013 GLuint id,
2014 GLenum pname,
2015 GLsizei bufSize,
2016 GLsizei *length,
2017 GLuint64 *params)
2018{
2019 if (!context->getExtensions().disjointTimerQuery)
2020 {
Jamie Madille0472f32018-11-27 16:32:45 -05002021 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002022 return false;
2023 }
2024
2025 if (!ValidateRobustEntryPoint(context, bufSize))
2026 {
2027 return false;
2028 }
2029
Brandon Jonesd1049182018-03-28 10:02:20 -07002030 GLsizei numParams = 0;
2031
2032 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002033 {
2034 return false;
2035 }
2036
Brandon Jonesd1049182018-03-28 10:02:20 -07002037 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002038 {
2039 return false;
2040 }
2041
Brandon Jonesd1049182018-03-28 10:02:20 -07002042 SetRobustLengthParam(length, numParams);
2043
Geoff Lang2186c382016-10-14 10:54:54 -04002044 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002045}
2046
Jamie Madill5b772312018-03-08 20:28:32 -05002047bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002048 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002049 GLint location,
2050 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002051 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002052{
Jiajia Qin5451d532017-11-16 17:16:34 +08002053 // TODO(Jiajia): Add image uniform check in future.
2054 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002055 {
Jamie Madille0472f32018-11-27 16:32:45 -05002056 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002057 return false;
2058 }
2059
Jiajia Qin5451d532017-11-16 17:16:34 +08002060 if (!program)
2061 {
Jamie Madille0472f32018-11-27 16:32:45 -05002062 context->validationError(GL_INVALID_OPERATION, kInvalidProgramName);
Jiajia Qin5451d532017-11-16 17:16:34 +08002063 return false;
2064 }
2065
2066 if (!program->isLinked())
2067 {
Jamie Madille0472f32018-11-27 16:32:45 -05002068 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiajia Qin5451d532017-11-16 17:16:34 +08002069 return false;
2070 }
2071
2072 if (location == -1)
2073 {
2074 // Silently ignore the uniform command
2075 return false;
2076 }
2077
2078 const auto &uniformLocations = program->getUniformLocations();
2079 size_t castedLocation = static_cast<size_t>(location);
2080 if (castedLocation >= uniformLocations.size())
2081 {
Jamie Madille0472f32018-11-27 16:32:45 -05002082 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002083 return false;
2084 }
2085
2086 const auto &uniformLocation = uniformLocations[castedLocation];
2087 if (uniformLocation.ignored)
2088 {
2089 // Silently ignore the uniform command
2090 return false;
2091 }
2092
2093 if (!uniformLocation.used())
2094 {
Jamie Madille0472f32018-11-27 16:32:45 -05002095 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002096 return false;
2097 }
2098
2099 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2100
2101 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002102 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002103 {
Jamie Madille0472f32018-11-27 16:32:45 -05002104 context->validationError(GL_INVALID_OPERATION, kInvalidUniformCount);
Jiajia Qin5451d532017-11-16 17:16:34 +08002105 return false;
2106 }
2107
2108 *uniformOut = &uniform;
2109 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002110}
2111
Jamie Madill5b772312018-03-08 20:28:32 -05002112bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002113 GLenum uniformType,
2114 GLsizei count,
2115 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002116{
Jiajia Qin5451d532017-11-16 17:16:34 +08002117 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2118 // It is compatible with INT or BOOL.
2119 // Do these cheap tests first, for a little extra speed.
2120 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002121 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002122 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002123 }
2124
Jiajia Qin5451d532017-11-16 17:16:34 +08002125 if (IsSamplerType(uniformType))
2126 {
2127 // Check that the values are in range.
2128 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2129 for (GLsizei i = 0; i < count; ++i)
2130 {
2131 if (value[i] < 0 || value[i] >= max)
2132 {
Jamie Madill610640f2018-11-21 17:28:41 -05002133 context->validationError(GL_INVALID_VALUE, "sampler uniform value out of range");
Jiajia Qin5451d532017-11-16 17:16:34 +08002134 return false;
2135 }
2136 }
2137 return true;
2138 }
2139
Jamie Madill610640f2018-11-21 17:28:41 -05002140 context->validationError(GL_INVALID_OPERATION, "wrong type of value for uniform");
Jiajia Qin5451d532017-11-16 17:16:34 +08002141 return false;
2142}
2143
Jamie Madill5b772312018-03-08 20:28:32 -05002144bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002145{
2146 // Check that the value type is compatible with uniform type.
2147 if (valueType == uniformType)
2148 {
2149 return true;
2150 }
2151
Jamie Madill610640f2018-11-21 17:28:41 -05002152 context->validationError(GL_INVALID_OPERATION, "wrong type of value for uniform");
Jiajia Qin5451d532017-11-16 17:16:34 +08002153 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002154}
2155
Jamie Madill5b772312018-03-08 20:28:32 -05002156bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002157{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002158 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002159 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002160 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2161 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002162}
2163
Jamie Madill5b772312018-03-08 20:28:32 -05002164bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002165{
2166 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002167 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002168 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2169 ValidateUniform1ivValue(context, uniform->type, count, value);
2170}
2171
Jamie Madill5b772312018-03-08 20:28:32 -05002172bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002173 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002174 GLint location,
2175 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002176 GLboolean transpose)
2177{
Geoff Lang92019432017-11-20 13:09:34 -05002178 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002179 {
Jamie Madille0472f32018-11-27 16:32:45 -05002180 context->validationError(GL_INVALID_VALUE, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04002181 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002182 }
2183
Jamie Madill62d31cb2015-09-11 13:25:51 -04002184 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002185 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002186 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2187 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002188}
2189
Jamie Madill5b772312018-03-08 20:28:32 -05002190bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002191{
2192 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2193 {
Jamie Madille0472f32018-11-27 16:32:45 -05002194 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langb1196682014-07-23 13:47:29 -04002195 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002196 }
2197
Jamie Madill0af26e12015-03-05 19:54:33 -05002198 const Caps &caps = context->getCaps();
2199
Jamie Madill893ab082014-05-16 16:56:10 -04002200 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2201 {
2202 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2203
Jamie Madill0af26e12015-03-05 19:54:33 -05002204 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002205 {
Jamie Madille0472f32018-11-27 16:32:45 -05002206 context->validationError(GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
Geoff Langb1196682014-07-23 13:47:29 -04002207 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002208 }
2209 }
2210
2211 switch (pname)
2212 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002213 case GL_TEXTURE_BINDING_2D:
2214 case GL_TEXTURE_BINDING_CUBE_MAP:
2215 case GL_TEXTURE_BINDING_3D:
2216 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002217 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002218 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002219 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002220 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002221 {
Jamie Madille0472f32018-11-27 16:32:45 -05002222 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03002223 return false;
2224 }
2225 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002226 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2227 if (!context->getExtensions().textureRectangle)
2228 {
Jamie Madill610640f2018-11-21 17:28:41 -05002229 context->validationError(GL_INVALID_ENUM,
2230 "ANGLE_texture_rectangle extension not present");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002231 return false;
2232 }
2233 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002234 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2235 if (!context->getExtensions().eglStreamConsumerExternal &&
2236 !context->getExtensions().eglImageExternal)
2237 {
Jamie Madill610640f2018-11-21 17:28:41 -05002238 context->validationError(GL_INVALID_ENUM,
2239 "Neither NV_EGL_stream_consumer_external "
2240 "nor GL_OES_EGL_image_external "
2241 "extensions enabled");
He Yunchaoced53ae2016-11-29 15:00:51 +08002242 return false;
2243 }
2244 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002245
He Yunchaoced53ae2016-11-29 15:00:51 +08002246 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2247 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002248 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002249 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2250 ASSERT(readFramebuffer);
2251
Jamie Madill610640f2018-11-21 17:28:41 -05002252 if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002253 {
Geoff Langb1196682014-07-23 13:47:29 -04002254 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002255 }
2256
Jamie Madille98b1b52018-03-08 09:47:23 -05002257 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002258 {
Jamie Madille0472f32018-11-27 16:32:45 -05002259 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002260 return false;
2261 }
2262
Jamie Madille98b1b52018-03-08 09:47:23 -05002263 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002264 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002265 {
Jamie Madille0472f32018-11-27 16:32:45 -05002266 context->validationError(GL_INVALID_OPERATION, kReadBufferNotAttached);
Geoff Langb1196682014-07-23 13:47:29 -04002267 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002268 }
2269 }
2270 break;
2271
He Yunchaoced53ae2016-11-29 15:00:51 +08002272 default:
2273 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002274 }
2275
2276 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002277 if (*numParams == 0)
2278 {
2279 return false;
2280 }
2281
2282 return true;
2283}
2284
Brandon Jonesd1049182018-03-28 10:02:20 -07002285bool ValidateGetBooleanvRobustANGLE(Context *context,
2286 GLenum pname,
2287 GLsizei bufSize,
2288 GLsizei *length,
2289 GLboolean *params)
2290{
2291 GLenum nativeType;
2292 unsigned int numParams = 0;
2293
2294 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2295 {
2296 return false;
2297 }
2298
2299 SetRobustLengthParam(length, numParams);
2300
2301 return true;
2302}
2303
2304bool ValidateGetFloatvRobustANGLE(Context *context,
2305 GLenum pname,
2306 GLsizei bufSize,
2307 GLsizei *length,
2308 GLfloat *params)
2309{
2310 GLenum nativeType;
2311 unsigned int numParams = 0;
2312
2313 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2314 {
2315 return false;
2316 }
2317
2318 SetRobustLengthParam(length, numParams);
2319
2320 return true;
2321}
2322
2323bool ValidateGetIntegervRobustANGLE(Context *context,
2324 GLenum pname,
2325 GLsizei bufSize,
2326 GLsizei *length,
2327 GLint *data)
2328{
2329 GLenum nativeType;
2330 unsigned int numParams = 0;
2331
2332 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2333 {
2334 return false;
2335 }
2336
2337 SetRobustLengthParam(length, numParams);
2338
2339 return true;
2340}
2341
2342bool ValidateGetInteger64vRobustANGLE(Context *context,
2343 GLenum pname,
2344 GLsizei bufSize,
2345 GLsizei *length,
2346 GLint64 *data)
2347{
2348 GLenum nativeType;
2349 unsigned int numParams = 0;
2350
2351 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2352 {
2353 return false;
2354 }
2355
2356 if (nativeType == GL_INT_64_ANGLEX)
2357 {
2358 CastStateValues(context, nativeType, pname, numParams, data);
2359 return false;
2360 }
2361
2362 SetRobustLengthParam(length, numParams);
2363 return true;
2364}
2365
Jamie Madill5b772312018-03-08 20:28:32 -05002366bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002367 GLenum pname,
2368 GLsizei bufSize,
2369 GLenum *nativeType,
2370 unsigned int *numParams)
2371{
2372 if (!ValidateRobustEntryPoint(context, bufSize))
2373 {
2374 return false;
2375 }
2376
2377 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2378 {
2379 return false;
2380 }
2381
2382 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002383 {
2384 return false;
2385 }
2386
2387 return true;
2388}
2389
Jamie Madill5b772312018-03-08 20:28:32 -05002390bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002391 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002392 GLint level,
2393 GLenum internalformat,
2394 bool isSubImage,
2395 GLint xoffset,
2396 GLint yoffset,
2397 GLint zoffset,
2398 GLint x,
2399 GLint y,
2400 GLsizei width,
2401 GLsizei height,
2402 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002403 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002404{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002405 TextureType texType = TextureTargetToType(target);
2406
Brandon Jones6cad5662017-06-14 13:25:13 -07002407 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002408 {
Jamie Madille0472f32018-11-27 16:32:45 -05002409 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07002410 return false;
2411 }
2412
2413 if (width < 0 || height < 0)
2414 {
Jamie Madille0472f32018-11-27 16:32:45 -05002415 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002416 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002417 }
2418
He Yunchaoced53ae2016-11-29 15:00:51 +08002419 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2420 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002421 {
Jamie Madille0472f32018-11-27 16:32:45 -05002422 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002423 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002424 }
2425
2426 if (border != 0)
2427 {
Jamie Madille0472f32018-11-27 16:32:45 -05002428 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002429 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002430 }
2431
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002432 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002433 {
Jamie Madille0472f32018-11-27 16:32:45 -05002434 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002435 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002436 }
2437
Jamie Madill43da7c42018-08-01 11:34:49 -04002438 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002439 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002440 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002441 {
Geoff Langb1196682014-07-23 13:47:29 -04002442 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002443 }
2444
Jamie Madille98b1b52018-03-08 09:47:23 -05002445 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002446 {
Geoff Langb1196682014-07-23 13:47:29 -04002447 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002448 }
2449
Martin Radev138064f2016-07-15 12:03:41 +03002450 if (readFramebuffer->getReadBufferState() == GL_NONE)
2451 {
Jamie Madille0472f32018-11-27 16:32:45 -05002452 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002453 return false;
2454 }
2455
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002456 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2457 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002458 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002459 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002460 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2461 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002462 {
Jamie Madille0472f32018-11-27 16:32:45 -05002463 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002464 return false;
2465 }
2466
Martin Radev04e2c3b2017-07-27 16:54:35 +03002467 // ANGLE_multiview spec, Revision 1:
2468 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2469 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002470 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2471 // framebuffer is more than one.
2472 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002473 {
Jamie Madill610640f2018-11-21 17:28:41 -05002474 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
2475 "The active read framebuffer object has multiview attachments.");
Martin Radev04e2c3b2017-07-27 16:54:35 +03002476 return false;
2477 }
2478
Jamie Madill43da7c42018-08-01 11:34:49 -04002479 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002480
Geoff Langaae65a42014-05-26 12:43:44 -04002481 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002482 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002483 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002484 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002485 maxDimension = caps.max2DTextureSize;
2486 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002487
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002488 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002489 maxDimension = caps.maxCubeMapTextureSize;
2490 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002491
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002492 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002493 maxDimension = caps.maxRectangleTextureSize;
2494 break;
2495
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002496 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002497 maxDimension = caps.max2DTextureSize;
2498 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002499
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002500 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002501 maxDimension = caps.max3DTextureSize;
2502 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002503
He Yunchaoced53ae2016-11-29 15:00:51 +08002504 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002505 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002506 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002507 }
2508
Jamie Madill43da7c42018-08-01 11:34:49 -04002509 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002510 if (!texture)
2511 {
Jamie Madille0472f32018-11-27 16:32:45 -05002512 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002513 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002514 }
2515
Geoff Lang69cce582015-09-17 13:20:36 -04002516 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002517 {
Jamie Madille0472f32018-11-27 16:32:45 -05002518 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002519 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002520 }
2521
Jamie Madill43da7c42018-08-01 11:34:49 -04002522 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002523 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002524 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002525
Geoff Lang966c9402017-04-18 12:38:27 -04002526 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002527 {
Jamie Madille0472f32018-11-27 16:32:45 -05002528 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Langa9be0dc2014-12-17 12:34:40 -05002529 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002530 }
2531
2532 if (isSubImage)
2533 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002534 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2535 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2536 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002537 {
Jamie Madille0472f32018-11-27 16:32:45 -05002538 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002539 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002540 }
2541 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002542 else
2543 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002544 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002545 {
Jamie Madille0472f32018-11-27 16:32:45 -05002546 context->validationError(GL_INVALID_VALUE, kCubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002547 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002548 }
2549
Geoff Langeb66a6e2016-10-31 13:06:12 -04002550 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002551 {
Jamie Madille0472f32018-11-27 16:32:45 -05002552 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002553 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002554 }
2555
2556 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002557 if (static_cast<int>(width) > maxLevelDimension ||
2558 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002559 {
Jamie Madille0472f32018-11-27 16:32:45 -05002560 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002561 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002562 }
2563 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002564
Jamie Madill0c8abca2016-07-22 20:21:26 -04002565 if (textureFormatOut)
2566 {
2567 *textureFormatOut = texture->getFormat(target, level);
2568 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002569
2570 // Detect texture copying feedback loops for WebGL.
2571 if (context->getExtensions().webglCompatibility)
2572 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002573 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002574 {
Jamie Madille0472f32018-11-27 16:32:45 -05002575 context->validationError(GL_INVALID_OPERATION, kFeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002576 return false;
2577 }
2578 }
2579
Jamie Madill560a8d82014-05-21 13:06:20 -04002580 return true;
2581}
2582
Jamie Madillb42162f2018-08-20 12:58:37 -04002583// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2584// completeness check.
2585const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002586{
2587 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002588 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002589
2590 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2591 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2592 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002593 VertexArray *vertexArray = state.getVertexArray();
2594 ASSERT(vertexArray);
2595
2596 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002597 {
Jamie Madille0472f32018-11-27 16:32:45 -05002598 return kBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002599 }
2600
2601 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2602 // Section 6.10 of the WebGL 1.0 spec.
2603 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002604 ASSERT(framebuffer);
2605
Jamie Madille7d80f32018-08-08 15:49:23 -04002606 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2607 {
2608 ASSERT(framebuffer);
2609 const FramebufferAttachment *dsAttachment =
2610 framebuffer->getStencilOrDepthStencilAttachment();
2611 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2612 ASSERT(stencilBits <= 8);
2613
2614 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2615 if (depthStencilState.stencilTest && stencilBits > 0)
2616 {
2617 GLuint maxStencilValue = (1 << stencilBits) - 1;
2618
2619 bool differentRefs =
2620 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2621 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2622 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2623 (depthStencilState.stencilBackWritemask & maxStencilValue);
2624 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2625 (depthStencilState.stencilBackMask & maxStencilValue);
2626
2627 if (differentRefs || differentWritemasks || differentMasks)
2628 {
2629 if (!extensions.webglCompatibility)
2630 {
2631 WARN() << "This ANGLE implementation does not support separate front/back "
2632 "stencil writemasks, reference values, or stencil mask values.";
2633 }
Jamie Madille0472f32018-11-27 16:32:45 -05002634 return kStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002635 }
2636 }
2637 }
2638
2639 if (!framebuffer->isComplete(context))
2640 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002641 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
Jamie Madille0472f32018-11-27 16:32:45 -05002642 return kDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002643 }
2644
2645 if (context->getStateCache().hasAnyEnabledClientAttrib())
2646 {
2647 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2648 {
2649 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2650 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2651 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2652 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madille0472f32018-11-27 16:32:45 -05002653 return kVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002654 }
2655
2656 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2657 {
2658 // This is an application error that would normally result in a crash, but we catch it
2659 // and return an error
Jamie Madille0472f32018-11-27 16:32:45 -05002660 return kVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002661 }
2662 }
2663
2664 // If we are running GLES1, there is no current program.
2665 if (context->getClientVersion() >= Version(2, 0))
2666 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002667 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002668 if (!program)
2669 {
Jamie Madille0472f32018-11-27 16:32:45 -05002670 return kProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002671 }
2672
2673 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2674 // vertex shader stage or fragment shader stage is a undefined behaviour.
2675 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2676 // produce undefined result.
2677 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2678 !program->hasLinkedShaderStage(ShaderType::Fragment))
2679 {
Jamie Madille0472f32018-11-27 16:32:45 -05002680 return kNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002681 }
2682
2683 if (!program->validateSamplers(nullptr, context->getCaps()))
2684 {
Jamie Madille0472f32018-11-27 16:32:45 -05002685 return kTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002686 }
2687
2688 if (extensions.multiview)
2689 {
2690 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2691 const int framebufferNumViews = framebuffer->getNumViews();
2692 if (framebufferNumViews != programNumViews)
2693 {
Jamie Madille0472f32018-11-27 16:32:45 -05002694 return kMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002695 }
2696
2697 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2698 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2699 framebufferNumViews > 1)
2700 {
Jamie Madille0472f32018-11-27 16:32:45 -05002701 return kMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002702 }
2703
2704 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2705 state.isQueryActive(QueryType::TimeElapsed))
2706 {
Jamie Madille0472f32018-11-27 16:32:45 -05002707 return kMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002708 }
2709 }
2710
2711 // Uniform buffer validation
2712 for (unsigned int uniformBlockIndex = 0;
2713 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2714 {
2715 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002716 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002717 const OffsetBindingPointer<Buffer> &uniformBuffer =
2718 state.getIndexedUniformBuffer(blockBinding);
2719
2720 if (uniformBuffer.get() == nullptr)
2721 {
2722 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002723 return kUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002724 }
2725
2726 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2727 if (uniformBufferSize < uniformBlock.dataSize)
2728 {
2729 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002730 return kUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002731 }
2732
2733 if (extensions.webglCompatibility &&
2734 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2735 {
Jamie Madille0472f32018-11-27 16:32:45 -05002736 return kUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002737 }
2738 }
2739
2740 // Do some additonal WebGL-specific validation
2741 if (extensions.webglCompatibility)
2742 {
2743 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2744 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2745 transformFeedbackObject->buffersBoundForOtherUse())
2746 {
Jamie Madille0472f32018-11-27 16:32:45 -05002747 return kTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002748 }
2749
2750 // Detect rendering feedback loops for WebGL.
2751 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2752 {
Jamie Madille0472f32018-11-27 16:32:45 -05002753 return kFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002754 }
2755
2756 // Detect that the vertex shader input types match the attribute types
2757 if (!ValidateVertexShaderAttributeTypeMatch(context))
2758 {
Jamie Madille0472f32018-11-27 16:32:45 -05002759 return kVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002760 }
2761
2762 // Detect that the color buffer types match the fragment shader output types
2763 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2764 {
Jamie Madille0472f32018-11-27 16:32:45 -05002765 return kDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002766 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002767
2768 const VertexArray *vao = context->getGLState().getVertexArray();
2769 if (vao->hasTransformFeedbackBindingConflict(context))
2770 {
Jamie Madille0472f32018-11-27 16:32:45 -05002771 return kVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002772 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002773 }
2774 }
2775
Jamie Madillb42162f2018-08-20 12:58:37 -04002776 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002777}
2778
Jamie Madill16e28fd2018-09-12 11:03:05 -04002779bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002780{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002781 const Extensions &extensions = context->getExtensions();
2782
Jamie Madill1aeb1312014-06-20 13:21:25 -04002783 switch (mode)
2784 {
Jamie Madill493f9572018-05-24 19:52:15 -04002785 case PrimitiveMode::Points:
2786 case PrimitiveMode::Lines:
2787 case PrimitiveMode::LineLoop:
2788 case PrimitiveMode::LineStrip:
2789 case PrimitiveMode::Triangles:
2790 case PrimitiveMode::TriangleStrip:
2791 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002792 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002793
Jamie Madill493f9572018-05-24 19:52:15 -04002794 case PrimitiveMode::LinesAdjacency:
2795 case PrimitiveMode::LineStripAdjacency:
2796 case PrimitiveMode::TrianglesAdjacency:
2797 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002798 if (!extensions.geometryShader)
2799 {
Jamie Madille0472f32018-11-27 16:32:45 -05002800 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaofccebff2018-03-08 13:51:02 +08002801 return false;
2802 }
2803 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002804 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002805 context->validationError(GL_INVALID_ENUM, kInvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002806 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002807 }
2808
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002809 // If we are running GLES1, there is no current program.
2810 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002811 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002812 const State &state = context->getGLState();
2813
Jamie Madill785e8a02018-10-04 17:42:00 -04002814 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002815 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002816
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002817 // Do geometry shader specific validations
2818 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002819 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002820 if (!IsCompatibleDrawModeWithGeometryShader(
2821 mode, program->getGeometryShaderInputPrimitiveType()))
2822 {
Jamie Madill610640f2018-11-21 17:28:41 -05002823 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002824 kIncompatibleDrawModeAgainstGeometryShader);
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002825 return false;
2826 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002827 }
2828 }
2829
Jamie Madill9fdaa492018-02-16 10:52:11 -05002830 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002831}
2832
Jamie Madill16e28fd2018-09-12 11:03:05 -04002833bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
2834{
2835 if (!context->getStateCache().isValidDrawMode(mode))
2836 {
2837 return ValidateDrawMode(context, mode);
2838 }
2839
2840 if (count < 0)
2841 {
Jamie Madille0472f32018-11-27 16:32:45 -05002842 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002843 return false;
2844 }
2845
2846 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2847 if (drawStatesError)
2848 {
2849 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2850
2851 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2852 // Incomplete.
2853 GLenum errorCode =
Jamie Madille0472f32018-11-27 16:32:45 -05002854 (errorMessage == kDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2855 : GL_INVALID_OPERATION);
Jamie Madill610640f2018-11-21 17:28:41 -05002856 context->validationError(errorCode, errorMessage);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002857 return false;
2858 }
2859
2860 return true;
2861}
2862
Jamie Madill5b772312018-03-08 20:28:32 -05002863bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002864 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002865 GLint first,
2866 GLsizei count,
2867 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002868{
Jamie Madillfd716582014-06-06 17:09:04 -04002869 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002870 {
Jamie Madille0472f32018-11-27 16:32:45 -05002871 context->validationError(GL_INVALID_VALUE, kNegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002872 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002873 }
2874
Jamie Madill16e28fd2018-09-12 11:03:05 -04002875 if (count < 0)
2876 {
Jamie Madille0472f32018-11-27 16:32:45 -05002877 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002878 return false;
2879 }
2880
Jamie Madill7f232932018-09-12 11:03:06 -04002881 const State &state = context->getGLState();
2882 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002883 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002884 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002885 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002886 if (!ValidateTransformFeedbackPrimitiveMode(context,
2887 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002888 {
Jamie Madille0472f32018-11-27 16:32:45 -05002889 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
James Darpinian30b604d2018-03-12 17:26:57 -07002890 return false;
2891 }
2892
2893 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2894 {
Jamie Madille0472f32018-11-27 16:32:45 -05002895 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferTooSmall);
James Darpinian30b604d2018-03-12 17:26:57 -07002896 return false;
2897 }
Jamie Madillfd716582014-06-06 17:09:04 -04002898 }
2899
Jamie Madill16e28fd2018-09-12 11:03:05 -04002900 if (!context->getStateCache().isValidDrawMode(mode))
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002901 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002902 return ValidateDrawMode(context, mode);
2903 }
2904
2905 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2906 if (drawStatesError)
2907 {
2908 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2909
2910 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2911 // Incomplete.
2912 GLenum errorCode =
Jamie Madille0472f32018-11-27 16:32:45 -05002913 (errorMessage == kDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2914 : GL_INVALID_OPERATION);
Jamie Madill610640f2018-11-21 17:28:41 -05002915 context->validationError(errorCode, errorMessage);
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002916 return false;
2917 }
2918
Corentin Wallez71168a02016-12-19 15:11:18 -08002919 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002920 // - first < 0 has been checked as an error condition.
2921 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002922 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002923 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002924 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002925 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002926 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2927 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2928 {
Jamie Madille0472f32018-11-27 16:32:45 -05002929 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madill9fdaa492018-02-16 10:52:11 -05002930 return false;
2931 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002932
Jamie Madill2da53562018-08-01 11:34:47 -04002933 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002934 {
2935 return false;
2936 }
Jamie Madillfd716582014-06-06 17:09:04 -04002937 }
2938
2939 return true;
2940}
2941
He Yunchaoced53ae2016-11-29 15:00:51 +08002942bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002943 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002944 GLint first,
2945 GLsizei count,
2946 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002947{
Geoff Lang63c5a592017-09-27 14:08:16 -04002948 if (!context->getExtensions().instancedArrays)
2949 {
Jamie Madille0472f32018-11-27 16:32:45 -05002950 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002951 return false;
2952 }
2953
Corentin Wallez170efbf2017-05-02 13:45:01 -04002954 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002955 {
2956 return false;
2957 }
2958
Corentin Wallez0dc97812017-06-22 14:38:44 -04002959 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002960}
2961
Jamie Madill493f9572018-05-24 19:52:15 -04002962bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, GLenum type)
Jamie Madillfd716582014-06-06 17:09:04 -04002963{
Jamie Madill250d33f2014-06-06 17:09:03 -04002964 switch (type)
2965 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002966 case GL_UNSIGNED_BYTE:
2967 case GL_UNSIGNED_SHORT:
2968 break;
2969 case GL_UNSIGNED_INT:
2970 if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
2971 {
Jamie Madille0472f32018-11-27 16:32:45 -05002972 context->validationError(GL_INVALID_ENUM, kTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002973 return false;
2974 }
2975 break;
2976 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002977 context->validationError(GL_INVALID_ENUM, kTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002978 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002979 }
2980
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002982
Jamie Madill43da7c42018-08-01 11:34:49 -04002983 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002984 if (curTransformFeedback && curTransformFeedback->isActive() &&
2985 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002986 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002987 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2988 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2989 if (context->getExtensions().geometryShader)
2990 {
2991 if (!ValidateTransformFeedbackPrimitiveMode(
2992 context, curTransformFeedback->getPrimitiveMode(), mode))
2993 {
Jamie Madille0472f32018-11-27 16:32:45 -05002994 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002995 return false;
2996 }
2997 }
2998 else
2999 {
3000 // It is an invalid operation to call DrawElements, DrawRangeElements or
3001 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
3002 // 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003003 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05003004 kUnsupportedDrawModeForTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003005 return false;
3006 }
Jamie Madill250d33f2014-06-06 17:09:03 -04003007 }
3008
Jiajia Qind9671222016-11-29 16:30:31 +08003009 return true;
3010}
3011
Jamie Madill5b772312018-03-08 20:28:32 -05003012bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003013 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003014 GLsizei count,
3015 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003016 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003017 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08003018{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003019 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003020 return false;
3021
3022 const State &state = context->getGLState();
3023
Corentin Wallez170efbf2017-05-02 13:45:01 -04003024 if (!ValidateDrawBase(context, mode, count))
3025 {
3026 return false;
3027 }
3028
Jamie Madill43da7c42018-08-01 11:34:49 -04003029 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003030 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003031
Jamie Madill43da7c42018-08-01 11:34:49 -04003032 GLuint typeBytes = GetTypeInfo(type).bytes;
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003033
3034 if (context->getExtensions().webglCompatibility)
3035 {
3036 ASSERT(isPow2(typeBytes) && typeBytes > 0);
3037 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3038 {
3039 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3040 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3041 // data type passed to the call, or an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003042 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003043 return false;
3044 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003045
3046 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3047 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3048 // error is generated.
3049 if (reinterpret_cast<intptr_t>(indices) < 0)
3050 {
Jamie Madille0472f32018-11-27 16:32:45 -05003051 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003052 return false;
3053 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003054 }
Jamie Madillcc73f242018-08-01 11:34:48 -04003055 else if (elementArrayBuffer && elementArrayBuffer->isMapped())
3056 {
3057 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3058 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the WebGL 2.0 API.
3059 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madill610640f2018-11-21 17:28:41 -05003060 context->validationError(GL_INVALID_OPERATION, "Index buffer is mapped.");
Jamie Madillcc73f242018-08-01 11:34:48 -04003061 return false;
3062 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003063
3064 if (context->getExtensions().webglCompatibility ||
3065 !context->getGLState().areClientArraysEnabled())
3066 {
Brandon Jones2a018152018-06-08 15:59:26 -07003067 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003068 {
3069 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003070 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3071 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003072 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003073 return false;
3074 }
3075 }
3076
Jamie Madill9fdaa492018-02-16 10:52:11 -05003077 if (count > 0 && !elementArrayBuffer && !indices)
Jamie Madillae3000b2014-08-25 15:47:51 -04003078 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003079 // This is an application error that would normally result in a crash, but we catch it and
3080 // return an error
Jamie Madill610640f2018-11-21 17:28:41 -05003081 context->validationError(GL_INVALID_OPERATION, "No element array buffer and no pointer.");
Jamie Madill9fdaa492018-02-16 10:52:11 -05003082 return false;
3083 }
3084
3085 if (count > 0 && elementArrayBuffer)
3086 {
3087 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3088 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3089 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3090 constexpr uint64_t kMaxTypeSize = 8;
3091 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3092 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3093 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3094
3095 uint64_t typeSize = typeBytes;
3096 uint64_t elementCount = static_cast<uint64_t>(count);
3097 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3098
3099 // Doing the multiplication here is overflow-safe
3100 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3101
3102 // The offset can be any value, check for overflows
3103 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3104 if (elementDataSizeNoOffset > kUint64Max - offset)
Jamie Madillae3000b2014-08-25 15:47:51 -04003105 {
Jamie Madille0472f32018-11-27 16:32:45 -05003106 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madill9fdaa492018-02-16 10:52:11 -05003107 return false;
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003108 }
Jamie Madill9fdaa492018-02-16 10:52:11 -05003109
3110 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3111 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003112 {
Jamie Madille0472f32018-11-27 16:32:45 -05003113 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9fdaa492018-02-16 10:52:11 -05003114 return false;
3115 }
3116
3117 ASSERT(isPow2(typeSize) && typeSize > 0);
3118 if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0)
3119 {
Jamie Madille0472f32018-11-27 16:32:45 -05003120 context->validationError(GL_INVALID_OPERATION, kMismatchedByteCountType);
Geoff Langb1196682014-07-23 13:47:29 -04003121 return false;
Jamie Madillae3000b2014-08-25 15:47:51 -04003122 }
James Darpiniane8a93c62018-01-04 18:02:24 -08003123
3124 if (context->getExtensions().webglCompatibility &&
3125 elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
3126 {
Jamie Madill610640f2018-11-21 17:28:41 -05003127 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05003128 kElementArrayBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003129 return false;
3130 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003131 }
3132
Jamie Madill2da53562018-08-01 11:34:47 -04003133 if (!context->getExtensions().robustBufferAccessBehavior && count > 0 && primcount > 0)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003134 {
3135 // Use the parameter buffer to retrieve and cache the index range.
Jamie Madillc1fd7372018-10-26 22:48:39 -04003136 IndexRange indexRange;
3137 ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003138
3139 // If we use an index greater than our maximum supported index range, return an error.
3140 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
3141 // return an error if possible here.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003142 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003143 {
Jamie Madille0472f32018-11-27 16:32:45 -05003144 context->validationError(GL_INVALID_OPERATION, kExceedsMaxElement);
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003145 return false;
3146 }
3147
Jamie Madill2da53562018-08-01 11:34:47 -04003148 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003149 {
3150 return false;
3151 }
3152
3153 // No op if there are no real indices in the index data (all are primitive restart).
Jamie Madill6f5444d2018-03-14 10:08:11 -04003154 return (indexRange.vertexIndexCount > 0);
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003155 }
3156
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003157 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003158}
3159
Jamie Madill5b772312018-03-08 20:28:32 -05003160bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003161 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003162 GLsizei count,
3163 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003164 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003165 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003166{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003167 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003168}
3169
Geoff Lang3edfe032015-09-04 16:38:24 -04003170bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003171 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003172 GLsizei count,
3173 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003174 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003175 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003176{
Geoff Lang63c5a592017-09-27 14:08:16 -04003177 if (!context->getExtensions().instancedArrays)
3178 {
Jamie Madille0472f32018-11-27 16:32:45 -05003179 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04003180 return false;
3181 }
3182
Corentin Wallez170efbf2017-05-02 13:45:01 -04003183 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003184 {
3185 return false;
3186 }
3187
Corentin Wallez0dc97812017-06-22 14:38:44 -04003188 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003189}
3190
He Yunchaoced53ae2016-11-29 15:00:51 +08003191bool ValidateFramebufferTextureBase(Context *context,
3192 GLenum target,
3193 GLenum attachment,
3194 GLuint texture,
3195 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003196{
Geoff Lange8afa902017-09-27 15:00:43 -04003197 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003198 {
Jamie Madille0472f32018-11-27 16:32:45 -05003199 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003200 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003201 }
3202
3203 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003204 {
3205 return false;
3206 }
3207
Jamie Madill55ec3b12014-07-03 10:38:57 -04003208 if (texture != 0)
3209 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003210 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003211
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003212 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003213 {
Jamie Madille0472f32018-11-27 16:32:45 -05003214 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04003215 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003216 }
3217
3218 if (level < 0)
3219 {
Jamie Madille0472f32018-11-27 16:32:45 -05003220 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04003221 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003222 }
3223 }
3224
Jamie Madill43da7c42018-08-01 11:34:49 -04003225 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003226 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003227
Jamie Madill84115c92015-04-23 15:00:07 -04003228 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003229 {
Jamie Madille0472f32018-11-27 16:32:45 -05003230 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003231 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003232 }
3233
3234 return true;
3235}
3236
Geoff Langb1196682014-07-23 13:47:29 -04003237bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003238{
3239 if (program == 0)
3240 {
Jamie Madille0472f32018-11-27 16:32:45 -05003241 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04003242 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003243 }
3244
Jamie Madill43da7c42018-08-01 11:34:49 -04003245 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003246 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003247 {
3248 return false;
3249 }
3250
Jamie Madill0063c512014-08-25 15:47:53 -04003251 if (!programObject || !programObject->isLinked())
3252 {
Jamie Madille0472f32018-11-27 16:32:45 -05003253 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003254 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003255 }
3256
Geoff Lang7dd2e102014-11-10 15:19:26 -05003257 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003258 {
Jamie Madille0472f32018-11-27 16:32:45 -05003259 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003260 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003261 }
3262
Jamie Madill0063c512014-08-25 15:47:53 -04003263 return true;
3264}
3265
Geoff Langf41d0ee2016-10-07 13:04:23 -04003266static bool ValidateSizedGetUniform(Context *context,
3267 GLuint program,
3268 GLint location,
3269 GLsizei bufSize,
3270 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003271{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003272 if (length)
3273 {
3274 *length = 0;
3275 }
3276
Jamie Madill78f41802014-08-25 15:47:55 -04003277 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003278 {
Jamie Madill78f41802014-08-25 15:47:55 -04003279 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003280 }
3281
Geoff Langf41d0ee2016-10-07 13:04:23 -04003282 if (bufSize < 0)
3283 {
Jamie Madille0472f32018-11-27 16:32:45 -05003284 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003285 return false;
3286 }
3287
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003288 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003289 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003290
Jamie Madill78f41802014-08-25 15:47:55 -04003291 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003292 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003293 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003294 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003295 {
Jamie Madille0472f32018-11-27 16:32:45 -05003296 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003297 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003298 }
3299
Geoff Langf41d0ee2016-10-07 13:04:23 -04003300 if (length)
3301 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003302 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003303 }
3304
Jamie Madill0063c512014-08-25 15:47:53 -04003305 return true;
3306}
3307
He Yunchaoced53ae2016-11-29 15:00:51 +08003308bool ValidateGetnUniformfvEXT(Context *context,
3309 GLuint program,
3310 GLint location,
3311 GLsizei bufSize,
3312 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003313{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003314 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003315}
3316
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003317bool ValidateGetnUniformfvRobustANGLE(Context *context,
3318 GLuint program,
3319 GLint location,
3320 GLsizei bufSize,
3321 GLsizei *length,
3322 GLfloat *params)
3323{
3324 UNIMPLEMENTED();
3325 return false;
3326}
3327
He Yunchaoced53ae2016-11-29 15:00:51 +08003328bool ValidateGetnUniformivEXT(Context *context,
3329 GLuint program,
3330 GLint location,
3331 GLsizei bufSize,
3332 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003333{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003334 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3335}
3336
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003337bool ValidateGetnUniformivRobustANGLE(Context *context,
3338 GLuint program,
3339 GLint location,
3340 GLsizei bufSize,
3341 GLsizei *length,
3342 GLint *params)
3343{
3344 UNIMPLEMENTED();
3345 return false;
3346}
3347
3348bool ValidateGetnUniformuivRobustANGLE(Context *context,
3349 GLuint program,
3350 GLint location,
3351 GLsizei bufSize,
3352 GLsizei *length,
3353 GLuint *params)
3354{
3355 UNIMPLEMENTED();
3356 return false;
3357}
3358
Geoff Langf41d0ee2016-10-07 13:04:23 -04003359bool ValidateGetUniformfvRobustANGLE(Context *context,
3360 GLuint program,
3361 GLint location,
3362 GLsizei bufSize,
3363 GLsizei *length,
3364 GLfloat *params)
3365{
3366 if (!ValidateRobustEntryPoint(context, bufSize))
3367 {
3368 return false;
3369 }
3370
Brandon Jonesd1049182018-03-28 10:02:20 -07003371 GLsizei writeLength = 0;
3372
Geoff Langf41d0ee2016-10-07 13:04:23 -04003373 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003374 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3375 {
3376 return false;
3377 }
3378
3379 SetRobustLengthParam(length, writeLength);
3380
3381 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003382}
3383
3384bool ValidateGetUniformivRobustANGLE(Context *context,
3385 GLuint program,
3386 GLint location,
3387 GLsizei bufSize,
3388 GLsizei *length,
3389 GLint *params)
3390{
3391 if (!ValidateRobustEntryPoint(context, bufSize))
3392 {
3393 return false;
3394 }
3395
Brandon Jonesd1049182018-03-28 10:02:20 -07003396 GLsizei writeLength = 0;
3397
Geoff Langf41d0ee2016-10-07 13:04:23 -04003398 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003399 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3400 {
3401 return false;
3402 }
3403
3404 SetRobustLengthParam(length, writeLength);
3405
3406 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003407}
3408
3409bool ValidateGetUniformuivRobustANGLE(Context *context,
3410 GLuint program,
3411 GLint location,
3412 GLsizei bufSize,
3413 GLsizei *length,
3414 GLuint *params)
3415{
3416 if (!ValidateRobustEntryPoint(context, bufSize))
3417 {
3418 return false;
3419 }
3420
3421 if (context->getClientMajorVersion() < 3)
3422 {
Jamie Madille0472f32018-11-27 16:32:45 -05003423 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003424 return false;
3425 }
3426
Brandon Jonesd1049182018-03-28 10:02:20 -07003427 GLsizei writeLength = 0;
3428
Geoff Langf41d0ee2016-10-07 13:04:23 -04003429 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003430 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3431 {
3432 return false;
3433 }
3434
3435 SetRobustLengthParam(length, writeLength);
3436
3437 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003438}
3439
He Yunchaoced53ae2016-11-29 15:00:51 +08003440bool ValidateDiscardFramebufferBase(Context *context,
3441 GLenum target,
3442 GLsizei numAttachments,
3443 const GLenum *attachments,
3444 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003445{
3446 if (numAttachments < 0)
3447 {
Jamie Madille0472f32018-11-27 16:32:45 -05003448 context->validationError(GL_INVALID_VALUE, kNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003449 return false;
3450 }
3451
3452 for (GLsizei i = 0; i < numAttachments; ++i)
3453 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003454 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003455 {
3456 if (defaultFramebuffer)
3457 {
Jamie Madille0472f32018-11-27 16:32:45 -05003458 context->validationError(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003459 return false;
3460 }
3461
3462 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3463 {
Jamie Madill610640f2018-11-21 17:28:41 -05003464 context->validationError(GL_INVALID_OPERATION,
3465 "Requested color attachment is "
3466 "greater than the maximum supported "
3467 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003468 return false;
3469 }
3470 }
3471 else
3472 {
3473 switch (attachments[i])
3474 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003475 case GL_DEPTH_ATTACHMENT:
3476 case GL_STENCIL_ATTACHMENT:
3477 case GL_DEPTH_STENCIL_ATTACHMENT:
3478 if (defaultFramebuffer)
3479 {
Jamie Madill610640f2018-11-21 17:28:41 -05003480 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003481 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003482 return false;
3483 }
3484 break;
3485 case GL_COLOR:
3486 case GL_DEPTH:
3487 case GL_STENCIL:
3488 if (!defaultFramebuffer)
3489 {
Jamie Madill610640f2018-11-21 17:28:41 -05003490 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003491 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003492 return false;
3493 }
3494 break;
3495 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003496 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003497 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003498 }
3499 }
3500 }
3501
3502 return true;
3503}
3504
Austin Kinross6ee1e782015-05-29 17:05:37 -07003505bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3506{
Jamie Madill007530e2017-12-28 14:27:04 -05003507 if (!context->getExtensions().debugMarker)
3508 {
3509 // The debug marker calls should not set error state
3510 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003511 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003512 return false;
3513 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003514
Jamie Madill007530e2017-12-28 14:27:04 -05003515 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003516 if (length < 0)
3517 {
3518 return false;
3519 }
3520
3521 if (marker == nullptr)
3522 {
3523 return false;
3524 }
3525
3526 return true;
3527}
3528
3529bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3530{
Jamie Madill007530e2017-12-28 14:27:04 -05003531 if (!context->getExtensions().debugMarker)
3532 {
3533 // The debug marker calls should not set error state
3534 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003535 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003536 return false;
3537 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003538
Jamie Madill007530e2017-12-28 14:27:04 -05003539 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003540 if (length < 0)
3541 {
3542 return false;
3543 }
3544
3545 if (length > 0 && marker == nullptr)
3546 {
3547 return false;
3548 }
3549
3550 return true;
3551}
3552
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003553bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003554{
Geoff Langa8406172015-07-21 16:53:39 -04003555 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3556 {
Jamie Madille0472f32018-11-27 16:32:45 -05003557 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003558 return false;
3559 }
3560
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003561 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003562 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003563 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003564 if (!context->getExtensions().eglImage)
3565 {
Jamie Madill610640f2018-11-21 17:28:41 -05003566 context->validationError(GL_INVALID_ENUM,
3567 "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003568 }
3569 break;
3570
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003571 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003572 if (!context->getExtensions().eglImageExternal)
3573 {
Jamie Madill610640f2018-11-21 17:28:41 -05003574 context->validationError(GL_INVALID_ENUM,
3575 "GL_TEXTURE_EXTERNAL_OES texture target "
3576 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003577 }
Geoff Langa8406172015-07-21 16:53:39 -04003578 break;
3579
3580 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003581 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003582 return false;
3583 }
3584
Rafael Cintron05a449a2018-06-20 18:08:04 -07003585 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003586
Jamie Madill61e16b42017-06-19 11:13:23 -04003587 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003588 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003589 {
Jamie Madill610640f2018-11-21 17:28:41 -05003590 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003591 return false;
3592 }
3593
Jamie Madill007530e2017-12-28 14:27:04 -05003594 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003595 {
Jamie Madill610640f2018-11-21 17:28:41 -05003596 context->validationError(GL_INVALID_OPERATION,
3597 "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003598 return false;
3599 }
3600
Yuly Novikov2eb54072018-08-22 16:41:26 -04003601 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003602 {
Jamie Madill610640f2018-11-21 17:28:41 -05003603 context->validationError(GL_INVALID_OPERATION,
3604 "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003605 return false;
3606 }
3607
Geoff Langdcab33b2015-07-21 13:03:16 -04003608 return true;
3609}
3610
3611bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003612 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003613 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003614{
Geoff Langa8406172015-07-21 16:53:39 -04003615 if (!context->getExtensions().eglImage)
3616 {
Jamie Madille0472f32018-11-27 16:32:45 -05003617 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003618 return false;
3619 }
3620
3621 switch (target)
3622 {
3623 case GL_RENDERBUFFER:
3624 break;
3625
3626 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003627 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003628 return false;
3629 }
3630
Rafael Cintron05a449a2018-06-20 18:08:04 -07003631 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003632
Jamie Madill61e16b42017-06-19 11:13:23 -04003633 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003634 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003635 {
Jamie Madill610640f2018-11-21 17:28:41 -05003636 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003637 return false;
3638 }
3639
Yuly Novikov2eb54072018-08-22 16:41:26 -04003640 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003641 {
Jamie Madill610640f2018-11-21 17:28:41 -05003642 context->validationError(GL_INVALID_OPERATION,
3643 "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003644 return false;
3645 }
3646
Geoff Langdcab33b2015-07-21 13:03:16 -04003647 return true;
3648}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003649
3650bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3651{
Geoff Lang36167ab2015-12-07 10:27:14 -05003652 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003653 {
3654 // The default VAO should always exist
3655 ASSERT(array != 0);
Jamie Madille0472f32018-11-27 16:32:45 -05003656 context->validationError(GL_INVALID_OPERATION, kInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003657 return false;
3658 }
3659
3660 return true;
3661}
3662
Geoff Langc5629752015-12-07 16:29:04 -05003663bool ValidateProgramBinaryBase(Context *context,
3664 GLuint program,
3665 GLenum binaryFormat,
3666 const void *binary,
3667 GLint length)
3668{
3669 Program *programObject = GetValidProgram(context, program);
3670 if (programObject == nullptr)
3671 {
3672 return false;
3673 }
3674
3675 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3676 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3677 programBinaryFormats.end())
3678 {
Jamie Madill610640f2018-11-21 17:28:41 -05003679 context->validationError(GL_INVALID_ENUM, "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003680 return false;
3681 }
3682
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003683 if (context->hasActiveTransformFeedback(program))
3684 {
3685 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05003686 context->validationError(GL_INVALID_OPERATION,
3687 "Cannot change program binary while program "
3688 "is associated with an active transform "
3689 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003690 return false;
3691 }
3692
Geoff Langc5629752015-12-07 16:29:04 -05003693 return true;
3694}
3695
3696bool ValidateGetProgramBinaryBase(Context *context,
3697 GLuint program,
3698 GLsizei bufSize,
3699 GLsizei *length,
3700 GLenum *binaryFormat,
3701 void *binary)
3702{
3703 Program *programObject = GetValidProgram(context, program);
3704 if (programObject == nullptr)
3705 {
3706 return false;
3707 }
3708
3709 if (!programObject->isLinked())
3710 {
Jamie Madille0472f32018-11-27 16:32:45 -05003711 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003712 return false;
3713 }
3714
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003715 if (context->getCaps().programBinaryFormats.empty())
3716 {
Jamie Madill610640f2018-11-21 17:28:41 -05003717 context->validationError(GL_INVALID_OPERATION, "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003718 return false;
3719 }
3720
Geoff Langc5629752015-12-07 16:29:04 -05003721 return true;
3722}
Jamie Madillc29968b2016-01-20 11:17:23 -05003723
Jamie Madill5b772312018-03-08 20:28:32 -05003724bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003725{
3726 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003727 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003728 {
Jamie Madille0472f32018-11-27 16:32:45 -05003729 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003730 return false;
3731 }
3732 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3733 {
Jamie Madille0472f32018-11-27 16:32:45 -05003734 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003735 return false;
3736 }
3737
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003738 ASSERT(context->getGLState().getDrawFramebuffer());
3739 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003740 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3741
3742 // This should come first before the check for the default frame buffer
3743 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3744 // rather than INVALID_OPERATION
3745 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3746 {
3747 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3748
3749 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003750 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3751 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003752 {
3753 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003754 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3755 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3756 // 3.1 is still a bit ambiguous about the error, but future specs are
3757 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madill610640f2018-11-21 17:28:41 -05003758 context->validationError(GL_INVALID_ENUM, "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003759 return false;
3760 }
3761 else if (bufs[colorAttachment] >= maxColorAttachment)
3762 {
Jamie Madill610640f2018-11-21 17:28:41 -05003763 context->validationError(GL_INVALID_OPERATION,
3764 "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003765 return false;
3766 }
3767 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3768 frameBufferId != 0)
3769 {
3770 // INVALID_OPERATION-GL is bound to buffer and ith argument
3771 // is not COLOR_ATTACHMENTi or NONE
Jamie Madill610640f2018-11-21 17:28:41 -05003772 context->validationError(GL_INVALID_OPERATION,
3773 "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003774 return false;
3775 }
3776 }
3777
3778 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3779 // and n is not 1 or bufs is bound to value other than BACK and NONE
3780 if (frameBufferId == 0)
3781 {
3782 if (n != 1)
3783 {
Jamie Madill610640f2018-11-21 17:28:41 -05003784 context->validationError(GL_INVALID_OPERATION,
3785 "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003786 return false;
3787 }
3788
3789 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3790 {
Jamie Madill610640f2018-11-21 17:28:41 -05003791 context->validationError(
3792 GL_INVALID_OPERATION,
3793 "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003794 return false;
3795 }
3796 }
3797
3798 return true;
3799}
3800
Geoff Lang496c02d2016-10-20 11:38:11 -07003801bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003802 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003803 GLenum pname,
3804 GLsizei *length,
3805 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003806{
Geoff Lang496c02d2016-10-20 11:38:11 -07003807 if (length)
3808 {
3809 *length = 0;
3810 }
3811
3812 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3813 {
Jamie Madill610640f2018-11-21 17:28:41 -05003814 context->validationError(
3815 GL_INVALID_OPERATION,
3816 "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003817 return false;
3818 }
3819
Corentin Walleze4477002017-12-01 14:39:58 -05003820 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003821 {
Jamie Madill610640f2018-11-21 17:28:41 -05003822 context->validationError(GL_INVALID_ENUM, "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003823 return false;
3824 }
3825
Geoff Lang496c02d2016-10-20 11:38:11 -07003826 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003827 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003828 case GL_BUFFER_MAP_POINTER:
3829 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003830
Geoff Lang496c02d2016-10-20 11:38:11 -07003831 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003832 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003833 return false;
3834 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003835
3836 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3837 // target bound to zero generate an INVALID_OPERATION error."
3838 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003839 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003840 {
Jamie Madill610640f2018-11-21 17:28:41 -05003841 context->validationError(GL_INVALID_OPERATION,
3842 "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003843 return false;
3844 }
3845
Geoff Lang496c02d2016-10-20 11:38:11 -07003846 if (length)
3847 {
3848 *length = 1;
3849 }
3850
Olli Etuaho4f667482016-03-30 15:56:35 +03003851 return true;
3852}
3853
Corentin Wallez336129f2017-10-17 15:55:40 -04003854bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003855{
Corentin Walleze4477002017-12-01 14:39:58 -05003856 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003857 {
Jamie Madille0472f32018-11-27 16:32:45 -05003858 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003859 return false;
3860 }
3861
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003862 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003863
3864 if (buffer == nullptr || !buffer->isMapped())
3865 {
Jamie Madill610640f2018-11-21 17:28:41 -05003866 context->validationError(GL_INVALID_OPERATION, "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003867 return false;
3868 }
3869
3870 return true;
3871}
3872
3873bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003874 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003875 GLintptr offset,
3876 GLsizeiptr length,
3877 GLbitfield access)
3878{
Corentin Walleze4477002017-12-01 14:39:58 -05003879 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003880 {
Jamie Madille0472f32018-11-27 16:32:45 -05003881 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003882 return false;
3883 }
3884
Brandon Jones6cad5662017-06-14 13:25:13 -07003885 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003886 {
Jamie Madille0472f32018-11-27 16:32:45 -05003887 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003888 return false;
3889 }
3890
3891 if (length < 0)
3892 {
Jamie Madille0472f32018-11-27 16:32:45 -05003893 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003894 return false;
3895 }
3896
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003897 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003898
3899 if (!buffer)
3900 {
Jamie Madill610640f2018-11-21 17:28:41 -05003901 context->validationError(GL_INVALID_OPERATION, "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003902 return false;
3903 }
3904
3905 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003906 CheckedNumeric<size_t> checkedOffset(offset);
3907 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003908
Jamie Madille2e406c2016-06-02 13:04:10 -04003909 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003910 {
Jamie Madill610640f2018-11-21 17:28:41 -05003911 context->validationError(GL_INVALID_VALUE,
3912 "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003913 return false;
3914 }
3915
3916 // Check for invalid bits in the mask
3917 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3918 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3919 GL_MAP_UNSYNCHRONIZED_BIT;
3920
3921 if (access & ~(allAccessBits))
3922 {
Jamie Madill610640f2018-11-21 17:28:41 -05003923 context->validationError(GL_INVALID_VALUE, "Invalid access bits");
Olli Etuaho4f667482016-03-30 15:56:35 +03003924 return false;
3925 }
3926
3927 if (length == 0)
3928 {
Jamie Madill610640f2018-11-21 17:28:41 -05003929 context->validationError(GL_INVALID_OPERATION, "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003930 return false;
3931 }
3932
3933 if (buffer->isMapped())
3934 {
Jamie Madill610640f2018-11-21 17:28:41 -05003935 context->validationError(GL_INVALID_OPERATION, "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003936 return false;
3937 }
3938
3939 // Check for invalid bit combinations
3940 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3941 {
Jamie Madill610640f2018-11-21 17:28:41 -05003942 context->validationError(GL_INVALID_OPERATION,
3943 "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003944 return false;
3945 }
3946
3947 GLbitfield writeOnlyBits =
3948 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3949
3950 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3951 {
Jamie Madill610640f2018-11-21 17:28:41 -05003952 context->validationError(GL_INVALID_OPERATION,
3953 "Invalid access bits when mapping buffer for reading");
Olli Etuaho4f667482016-03-30 15:56:35 +03003954 return false;
3955 }
3956
3957 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3958 {
Jamie Madill610640f2018-11-21 17:28:41 -05003959 context->validationError(
3960 GL_INVALID_OPERATION,
3961 "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003962 return false;
3963 }
Geoff Lang79f71042017-08-14 16:43:43 -04003964
3965 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003966}
3967
3968bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003969 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003970 GLintptr offset,
3971 GLsizeiptr length)
3972{
Brandon Jones6cad5662017-06-14 13:25:13 -07003973 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003974 {
Jamie Madille0472f32018-11-27 16:32:45 -05003975 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003976 return false;
3977 }
3978
3979 if (length < 0)
3980 {
Jamie Madille0472f32018-11-27 16:32:45 -05003981 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003982 return false;
3983 }
3984
Corentin Walleze4477002017-12-01 14:39:58 -05003985 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003986 {
Jamie Madille0472f32018-11-27 16:32:45 -05003987 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003988 return false;
3989 }
3990
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003991 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003992
3993 if (buffer == nullptr)
3994 {
Jamie Madill610640f2018-11-21 17:28:41 -05003995 context->validationError(GL_INVALID_OPERATION, "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003996 return false;
3997 }
3998
3999 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
4000 {
Jamie Madill610640f2018-11-21 17:28:41 -05004001 context->validationError(GL_INVALID_OPERATION,
4002 "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004003 return false;
4004 }
4005
4006 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04004007 CheckedNumeric<size_t> checkedOffset(offset);
4008 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03004009
Jamie Madille2e406c2016-06-02 13:04:10 -04004010 if (!checkedSize.IsValid() ||
4011 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03004012 {
Jamie Madill610640f2018-11-21 17:28:41 -05004013 context->validationError(GL_INVALID_VALUE,
4014 "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004015 return false;
4016 }
4017
4018 return true;
4019}
4020
Olli Etuaho41997e72016-03-10 13:38:39 +02004021bool ValidateGenOrDelete(Context *context, GLint n)
4022{
4023 if (n < 0)
4024 {
Jamie Madille0472f32018-11-27 16:32:45 -05004025 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004026 return false;
4027 }
4028 return true;
4029}
4030
Jamie Madill5b772312018-03-08 20:28:32 -05004031bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004032{
4033 if (!context->getExtensions().robustClientMemory)
4034 {
Jamie Madill610640f2018-11-21 17:28:41 -05004035 context->validationError(GL_INVALID_OPERATION,
4036 "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004037 return false;
4038 }
4039
4040 if (bufSize < 0)
4041 {
Jamie Madille0472f32018-11-27 16:32:45 -05004042 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004043 return false;
4044 }
4045
4046 return true;
4047}
4048
Jamie Madill5b772312018-03-08 20:28:32 -05004049bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004050{
4051 if (bufSize < numParams)
4052 {
Jamie Madill610640f2018-11-21 17:28:41 -05004053 context->validationError(GL_INVALID_OPERATION,
4054 "More parameters are required than were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004055 return false;
4056 }
4057
4058 return true;
4059}
4060
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004061bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004062 GLenum target,
4063 GLenum attachment,
4064 GLenum pname,
4065 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004066{
Geoff Lange8afa902017-09-27 15:00:43 -04004067 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004068 {
Jamie Madille0472f32018-11-27 16:32:45 -05004069 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004070 return false;
4071 }
4072
4073 int clientVersion = context->getClientMajorVersion();
4074
4075 switch (pname)
4076 {
4077 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4078 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4079 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4080 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4081 break;
4082
Martin Radeve5285d22017-07-14 16:23:53 +03004083 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4084 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4085 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4086 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4087 if (clientVersion < 3 || !context->getExtensions().multiview)
4088 {
Jamie Madille0472f32018-11-27 16:32:45 -05004089 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03004090 return false;
4091 }
4092 break;
4093
Geoff Langff5b2d52016-09-07 11:32:23 -04004094 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4095 if (clientVersion < 3 && !context->getExtensions().sRGB)
4096 {
Jamie Madille0472f32018-11-27 16:32:45 -05004097 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004098 return false;
4099 }
4100 break;
4101
4102 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4103 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4104 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4105 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4106 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4107 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4108 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4109 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4110 if (clientVersion < 3)
4111 {
Jamie Madille0472f32018-11-27 16:32:45 -05004112 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004113 return false;
4114 }
4115 break;
4116
Jiawei Shaoa8802472018-05-28 11:17:47 +08004117 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4118 if (!context->getExtensions().geometryShader)
4119 {
Jamie Madille0472f32018-11-27 16:32:45 -05004120 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08004121 return false;
4122 }
4123 break;
4124
Geoff Langff5b2d52016-09-07 11:32:23 -04004125 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004126 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04004127 return false;
4128 }
4129
4130 // Determine if the attachment is a valid enum
4131 switch (attachment)
4132 {
4133 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004134 case GL_DEPTH:
4135 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004136 if (clientVersion < 3)
4137 {
Jamie Madille0472f32018-11-27 16:32:45 -05004138 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004139 return false;
4140 }
4141 break;
4142
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004143 case GL_DEPTH_STENCIL_ATTACHMENT:
4144 if (clientVersion < 3 && !context->isWebGL1())
4145 {
Jamie Madille0472f32018-11-27 16:32:45 -05004146 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004147 return false;
4148 }
4149 break;
4150
Geoff Langfa125c92017-10-24 13:01:46 -04004151 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004152 case GL_DEPTH_ATTACHMENT:
4153 case GL_STENCIL_ATTACHMENT:
4154 break;
4155
4156 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004157 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4158 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004159 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4160 {
Jamie Madille0472f32018-11-27 16:32:45 -05004161 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004162 return false;
4163 }
4164 break;
4165 }
4166
4167 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4168 ASSERT(framebuffer);
4169
4170 if (framebuffer->id() == 0)
4171 {
4172 if (clientVersion < 3)
4173 {
Jamie Madille0472f32018-11-27 16:32:45 -05004174 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004175 return false;
4176 }
4177
4178 switch (attachment)
4179 {
4180 case GL_BACK:
4181 case GL_DEPTH:
4182 case GL_STENCIL:
4183 break;
4184
4185 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004186 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004187 return false;
4188 }
4189 }
4190 else
4191 {
4192 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4193 {
4194 // Valid attachment query
4195 }
4196 else
4197 {
4198 switch (attachment)
4199 {
4200 case GL_DEPTH_ATTACHMENT:
4201 case GL_STENCIL_ATTACHMENT:
4202 break;
4203
4204 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004205 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004206 {
Jamie Madille0472f32018-11-27 16:32:45 -05004207 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004208 return false;
4209 }
4210 break;
4211
4212 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004213 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004214 return false;
4215 }
4216 }
4217 }
4218
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004219 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004220 if (attachmentObject)
4221 {
4222 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4223 attachmentObject->type() == GL_TEXTURE ||
4224 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4225
4226 switch (pname)
4227 {
4228 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4229 if (attachmentObject->type() != GL_RENDERBUFFER &&
4230 attachmentObject->type() != GL_TEXTURE)
4231 {
Jamie Madille0472f32018-11-27 16:32:45 -05004232 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004233 return false;
4234 }
4235 break;
4236
4237 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4238 if (attachmentObject->type() != GL_TEXTURE)
4239 {
Jamie Madille0472f32018-11-27 16:32:45 -05004240 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004241 return false;
4242 }
4243 break;
4244
4245 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4246 if (attachmentObject->type() != GL_TEXTURE)
4247 {
Jamie Madille0472f32018-11-27 16:32:45 -05004248 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004249 return false;
4250 }
4251 break;
4252
4253 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4254 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4255 {
Jamie Madille0472f32018-11-27 16:32:45 -05004256 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004257 return false;
4258 }
4259 break;
4260
4261 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4262 if (attachmentObject->type() != GL_TEXTURE)
4263 {
Jamie Madille0472f32018-11-27 16:32:45 -05004264 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004265 return false;
4266 }
4267 break;
4268
4269 default:
4270 break;
4271 }
4272 }
4273 else
4274 {
4275 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4276 // is NONE, then querying any other pname will generate INVALID_ENUM.
4277
4278 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4279 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4280 // INVALID_OPERATION for all other pnames
4281
4282 switch (pname)
4283 {
4284 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4285 break;
4286
4287 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4288 if (clientVersion < 3)
4289 {
Jamie Madill610640f2018-11-21 17:28:41 -05004290 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004291 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004292 return false;
4293 }
4294 break;
4295
4296 default:
4297 if (clientVersion < 3)
4298 {
Jamie Madill610640f2018-11-21 17:28:41 -05004299 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004300 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004301 return false;
4302 }
4303 else
4304 {
Jamie Madill610640f2018-11-21 17:28:41 -05004305 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05004306 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004307 return false;
4308 }
4309 }
4310 }
4311
Martin Radeve5285d22017-07-14 16:23:53 +03004312 if (numParams)
4313 {
4314 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4315 {
4316 // Only when the viewport offsets are queried we can have a varying number of output
4317 // parameters.
4318 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4319 *numParams = numViews * 2;
4320 }
4321 else
4322 {
4323 // For all other queries we can have only one output parameter.
4324 *numParams = 1;
4325 }
4326 }
4327
Geoff Langff5b2d52016-09-07 11:32:23 -04004328 return true;
4329}
4330
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004331bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004332 GLenum target,
4333 GLenum attachment,
4334 GLenum pname,
4335 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004336 GLsizei *length,
4337 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004338{
4339 if (!ValidateRobustEntryPoint(context, bufSize))
4340 {
4341 return false;
4342 }
4343
Brandon Jonesd1049182018-03-28 10:02:20 -07004344 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004345 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004346 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004347 {
4348 return false;
4349 }
4350
Brandon Jonesd1049182018-03-28 10:02:20 -07004351 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004352 {
4353 return false;
4354 }
4355
Brandon Jonesd1049182018-03-28 10:02:20 -07004356 SetRobustLengthParam(length, numParams);
4357
Geoff Langff5b2d52016-09-07 11:32:23 -04004358 return true;
4359}
4360
Jamie Madill5b772312018-03-08 20:28:32 -05004361bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004362 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004363 GLenum pname,
4364 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004365 GLsizei *length,
4366 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004367{
4368 if (!ValidateRobustEntryPoint(context, bufSize))
4369 {
4370 return false;
4371 }
4372
Brandon Jonesd1049182018-03-28 10:02:20 -07004373 GLsizei numParams = 0;
4374
4375 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004376 {
4377 return false;
4378 }
4379
Brandon Jonesd1049182018-03-28 10:02:20 -07004380 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004381 {
4382 return false;
4383 }
4384
Brandon Jonesd1049182018-03-28 10:02:20 -07004385 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004386 return true;
4387}
4388
Jamie Madill5b772312018-03-08 20:28:32 -05004389bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004390 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004391 GLenum pname,
4392 GLsizei bufSize,
4393 GLsizei *length,
4394 GLint64 *params)
4395{
Brandon Jonesd1049182018-03-28 10:02:20 -07004396 GLsizei numParams = 0;
4397
Geoff Langebebe1c2016-10-14 12:01:31 -04004398 if (!ValidateRobustEntryPoint(context, bufSize))
4399 {
4400 return false;
4401 }
4402
Brandon Jonesd1049182018-03-28 10:02:20 -07004403 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004404 {
4405 return false;
4406 }
4407
Brandon Jonesd1049182018-03-28 10:02:20 -07004408 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004409 {
4410 return false;
4411 }
4412
Brandon Jonesd1049182018-03-28 10:02:20 -07004413 SetRobustLengthParam(length, numParams);
4414
Geoff Langff5b2d52016-09-07 11:32:23 -04004415 return true;
4416}
4417
Jamie Madill5b772312018-03-08 20:28:32 -05004418bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004419{
4420 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004421 if (numParams)
4422 {
4423 *numParams = 1;
4424 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004425
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004426 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4427 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4428 ? GetValidProgramNoResolve(context, program)
4429 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004430 if (!programObject)
4431 {
4432 return false;
4433 }
4434
4435 switch (pname)
4436 {
4437 case GL_DELETE_STATUS:
4438 case GL_LINK_STATUS:
4439 case GL_VALIDATE_STATUS:
4440 case GL_INFO_LOG_LENGTH:
4441 case GL_ATTACHED_SHADERS:
4442 case GL_ACTIVE_ATTRIBUTES:
4443 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4444 case GL_ACTIVE_UNIFORMS:
4445 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4446 break;
4447
4448 case GL_PROGRAM_BINARY_LENGTH:
4449 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4450 {
Jamie Madill610640f2018-11-21 17:28:41 -05004451 context->validationError(GL_INVALID_ENUM,
4452 "Querying GL_PROGRAM_BINARY_LENGTH "
4453 "requires GL_OES_get_program_binary or "
4454 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004455 return false;
4456 }
4457 break;
4458
4459 case GL_ACTIVE_UNIFORM_BLOCKS:
4460 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4461 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4462 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4463 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4464 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4465 if (context->getClientMajorVersion() < 3)
4466 {
Jamie Madille0472f32018-11-27 16:32:45 -05004467 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004468 return false;
4469 }
4470 break;
4471
Yunchao He61afff12017-03-14 15:34:03 +08004472 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004473 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004474 if (context->getClientVersion() < Version(3, 1))
4475 {
Jamie Madille0472f32018-11-27 16:32:45 -05004476 context->validationError(GL_INVALID_ENUM, kES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004477 return false;
4478 }
4479 break;
4480
Jiawei Shao6ae51612018-02-23 14:03:25 +08004481 case GL_COMPUTE_WORK_GROUP_SIZE:
4482 if (context->getClientVersion() < Version(3, 1))
4483 {
Jamie Madille0472f32018-11-27 16:32:45 -05004484 context->validationError(GL_INVALID_ENUM, kES31Required);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004485 return false;
4486 }
4487
4488 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4489 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4490 // program which has not been linked successfully, or which does not contain objects to
4491 // form a compute shader.
4492 if (!programObject->isLinked())
4493 {
Jamie Madille0472f32018-11-27 16:32:45 -05004494 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004495 return false;
4496 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004497 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004498 {
Jamie Madille0472f32018-11-27 16:32:45 -05004499 context->validationError(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004500 return false;
4501 }
4502 break;
4503
Jiawei Shao447bfac2018-03-14 14:23:40 +08004504 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4505 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4506 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4507 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4508 if (!context->getExtensions().geometryShader)
4509 {
Jamie Madille0472f32018-11-27 16:32:45 -05004510 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004511 return false;
4512 }
4513
4514 // [EXT_geometry_shader] Chapter 7.12
4515 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4516 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4517 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4518 // successfully, or which does not contain objects to form a geometry shader.
4519 if (!programObject->isLinked())
4520 {
Jamie Madille0472f32018-11-27 16:32:45 -05004521 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004522 return false;
4523 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004524 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004525 {
Jamie Madille0472f32018-11-27 16:32:45 -05004526 context->validationError(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004527 return false;
4528 }
4529 break;
4530
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004531 case GL_COMPLETION_STATUS_KHR:
4532 if (!context->getExtensions().parallelShaderCompile)
4533 {
Jamie Madille0472f32018-11-27 16:32:45 -05004534 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004535 return false;
4536 }
4537 break;
4538
Geoff Langff5b2d52016-09-07 11:32:23 -04004539 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004540 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004541 return false;
4542 }
4543
4544 return true;
4545}
4546
4547bool ValidateGetProgramivRobustANGLE(Context *context,
4548 GLuint program,
4549 GLenum pname,
4550 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004551 GLsizei *length,
4552 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004553{
4554 if (!ValidateRobustEntryPoint(context, bufSize))
4555 {
4556 return false;
4557 }
4558
Brandon Jonesd1049182018-03-28 10:02:20 -07004559 GLsizei numParams = 0;
4560
4561 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004562 {
4563 return false;
4564 }
4565
Brandon Jonesd1049182018-03-28 10:02:20 -07004566 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004567 {
4568 return false;
4569 }
4570
Brandon Jonesd1049182018-03-28 10:02:20 -07004571 SetRobustLengthParam(length, numParams);
4572
Geoff Langff5b2d52016-09-07 11:32:23 -04004573 return true;
4574}
4575
Geoff Lang740d9022016-10-07 11:20:52 -04004576bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4577 GLenum target,
4578 GLenum pname,
4579 GLsizei bufSize,
4580 GLsizei *length,
4581 GLint *params)
4582{
4583 if (!ValidateRobustEntryPoint(context, bufSize))
4584 {
4585 return false;
4586 }
4587
Brandon Jonesd1049182018-03-28 10:02:20 -07004588 GLsizei numParams = 0;
4589
4590 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004591 {
4592 return false;
4593 }
4594
Brandon Jonesd1049182018-03-28 10:02:20 -07004595 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004596 {
4597 return false;
4598 }
4599
Brandon Jonesd1049182018-03-28 10:02:20 -07004600 SetRobustLengthParam(length, numParams);
4601
Geoff Lang740d9022016-10-07 11:20:52 -04004602 return true;
4603}
4604
Geoff Langd7d0ed32016-10-07 11:33:51 -04004605bool ValidateGetShaderivRobustANGLE(Context *context,
4606 GLuint shader,
4607 GLenum pname,
4608 GLsizei bufSize,
4609 GLsizei *length,
4610 GLint *params)
4611{
4612 if (!ValidateRobustEntryPoint(context, bufSize))
4613 {
4614 return false;
4615 }
4616
Brandon Jonesd1049182018-03-28 10:02:20 -07004617 GLsizei numParams = 0;
4618
4619 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004620 {
4621 return false;
4622 }
4623
Brandon Jonesd1049182018-03-28 10:02:20 -07004624 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004625 {
4626 return false;
4627 }
4628
Brandon Jonesd1049182018-03-28 10:02:20 -07004629 SetRobustLengthParam(length, numParams);
4630
Geoff Langd7d0ed32016-10-07 11:33:51 -04004631 return true;
4632}
4633
Geoff Langc1984ed2016-10-07 12:41:00 -04004634bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004635 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004636 GLenum pname,
4637 GLsizei bufSize,
4638 GLsizei *length,
4639 GLfloat *params)
4640{
4641 if (!ValidateRobustEntryPoint(context, bufSize))
4642 {
4643 return false;
4644 }
4645
Brandon Jonesd1049182018-03-28 10:02:20 -07004646 GLsizei numParams = 0;
4647
4648 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004649 {
4650 return false;
4651 }
4652
Brandon Jonesd1049182018-03-28 10:02:20 -07004653 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004654 {
4655 return false;
4656 }
4657
Brandon Jonesd1049182018-03-28 10:02:20 -07004658 SetRobustLengthParam(length, numParams);
4659
Geoff Langc1984ed2016-10-07 12:41:00 -04004660 return true;
4661}
4662
Geoff Langc1984ed2016-10-07 12:41:00 -04004663bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004664 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004665 GLenum pname,
4666 GLsizei bufSize,
4667 GLsizei *length,
4668 GLint *params)
4669{
Brandon Jonesd1049182018-03-28 10:02:20 -07004670
Geoff Langc1984ed2016-10-07 12:41:00 -04004671 if (!ValidateRobustEntryPoint(context, bufSize))
4672 {
4673 return false;
4674 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004675 GLsizei numParams = 0;
4676 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004677 {
4678 return false;
4679 }
4680
Brandon Jonesd1049182018-03-28 10:02:20 -07004681 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004682 {
4683 return false;
4684 }
4685
Brandon Jonesd1049182018-03-28 10:02:20 -07004686 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004687 return true;
4688}
4689
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004690bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4691 TextureType target,
4692 GLenum pname,
4693 GLsizei bufSize,
4694 GLsizei *length,
4695 GLint *params)
4696{
4697 UNIMPLEMENTED();
4698 return false;
4699}
4700
4701bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4702 TextureType target,
4703 GLenum pname,
4704 GLsizei bufSize,
4705 GLsizei *length,
4706 GLuint *params)
4707{
4708 UNIMPLEMENTED();
4709 return false;
4710}
4711
Geoff Langc1984ed2016-10-07 12:41:00 -04004712bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004713 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004714 GLenum pname,
4715 GLsizei bufSize,
4716 const GLfloat *params)
4717{
4718 if (!ValidateRobustEntryPoint(context, bufSize))
4719 {
4720 return false;
4721 }
4722
Till Rathmannb8543632018-10-02 19:46:14 +02004723 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004724}
4725
Geoff Langc1984ed2016-10-07 12:41:00 -04004726bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004727 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004728 GLenum pname,
4729 GLsizei bufSize,
4730 const GLint *params)
4731{
4732 if (!ValidateRobustEntryPoint(context, bufSize))
4733 {
4734 return false;
4735 }
4736
Till Rathmannb8543632018-10-02 19:46:14 +02004737 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004738}
4739
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004740bool ValidateTexParameterIivRobustANGLE(Context *context,
4741 TextureType target,
4742 GLenum pname,
4743 GLsizei bufSize,
4744 const GLint *params)
4745{
4746 UNIMPLEMENTED();
4747 return false;
4748}
4749
4750bool ValidateTexParameterIuivRobustANGLE(Context *context,
4751 TextureType target,
4752 GLenum pname,
4753 GLsizei bufSize,
4754 const GLuint *params)
4755{
4756 UNIMPLEMENTED();
4757 return false;
4758}
4759
Geoff Langc1984ed2016-10-07 12:41:00 -04004760bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4761 GLuint sampler,
4762 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004763 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004764 GLsizei *length,
4765 GLfloat *params)
4766{
4767 if (!ValidateRobustEntryPoint(context, bufSize))
4768 {
4769 return false;
4770 }
4771
Brandon Jonesd1049182018-03-28 10:02:20 -07004772 GLsizei numParams = 0;
4773
4774 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004775 {
4776 return false;
4777 }
4778
Brandon Jonesd1049182018-03-28 10:02:20 -07004779 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004780 {
4781 return false;
4782 }
4783
Brandon Jonesd1049182018-03-28 10:02:20 -07004784 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004785 return true;
4786}
4787
Geoff Langc1984ed2016-10-07 12:41:00 -04004788bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4789 GLuint sampler,
4790 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004791 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004792 GLsizei *length,
4793 GLint *params)
4794{
4795 if (!ValidateRobustEntryPoint(context, bufSize))
4796 {
4797 return false;
4798 }
4799
Brandon Jonesd1049182018-03-28 10:02:20 -07004800 GLsizei numParams = 0;
4801
4802 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004803 {
4804 return false;
4805 }
4806
Brandon Jonesd1049182018-03-28 10:02:20 -07004807 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004808 {
4809 return false;
4810 }
4811
Brandon Jonesd1049182018-03-28 10:02:20 -07004812 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004813 return true;
4814}
4815
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004816bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4817 GLuint sampler,
4818 GLenum pname,
4819 GLsizei bufSize,
4820 GLsizei *length,
4821 GLint *params)
4822{
4823 UNIMPLEMENTED();
4824 return false;
4825}
4826
4827bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4828 GLuint sampler,
4829 GLenum pname,
4830 GLsizei bufSize,
4831 GLsizei *length,
4832 GLuint *params)
4833{
4834 UNIMPLEMENTED();
4835 return false;
4836}
4837
Geoff Langc1984ed2016-10-07 12:41:00 -04004838bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4839 GLuint sampler,
4840 GLenum pname,
4841 GLsizei bufSize,
4842 const GLfloat *params)
4843{
4844 if (!ValidateRobustEntryPoint(context, bufSize))
4845 {
4846 return false;
4847 }
4848
Till Rathmannb8543632018-10-02 19:46:14 +02004849 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004850}
4851
Geoff Langc1984ed2016-10-07 12:41:00 -04004852bool ValidateSamplerParameterivRobustANGLE(Context *context,
4853 GLuint sampler,
4854 GLenum pname,
4855 GLsizei bufSize,
4856 const GLint *params)
4857{
4858 if (!ValidateRobustEntryPoint(context, bufSize))
4859 {
4860 return false;
4861 }
4862
Till Rathmannb8543632018-10-02 19:46:14 +02004863 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004864}
4865
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004866bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4867 GLuint sampler,
4868 GLenum pname,
4869 GLsizei bufSize,
4870 const GLint *param)
4871{
4872 UNIMPLEMENTED();
4873 return false;
4874}
4875
4876bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4877 GLuint sampler,
4878 GLenum pname,
4879 GLsizei bufSize,
4880 const GLuint *param)
4881{
4882 UNIMPLEMENTED();
4883 return false;
4884}
4885
Geoff Lang0b031062016-10-13 14:30:04 -04004886bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4887 GLuint index,
4888 GLenum pname,
4889 GLsizei bufSize,
4890 GLsizei *length,
4891 GLfloat *params)
4892{
4893 if (!ValidateRobustEntryPoint(context, bufSize))
4894 {
4895 return false;
4896 }
4897
Brandon Jonesd1049182018-03-28 10:02:20 -07004898 GLsizei writeLength = 0;
4899
4900 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004901 {
4902 return false;
4903 }
4904
Brandon Jonesd1049182018-03-28 10:02:20 -07004905 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004906 {
4907 return false;
4908 }
4909
Brandon Jonesd1049182018-03-28 10:02:20 -07004910 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004911 return true;
4912}
4913
Geoff Lang0b031062016-10-13 14:30:04 -04004914bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4915 GLuint index,
4916 GLenum pname,
4917 GLsizei bufSize,
4918 GLsizei *length,
4919 GLint *params)
4920{
4921 if (!ValidateRobustEntryPoint(context, bufSize))
4922 {
4923 return false;
4924 }
4925
Brandon Jonesd1049182018-03-28 10:02:20 -07004926 GLsizei writeLength = 0;
4927
4928 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004929 {
4930 return false;
4931 }
4932
Brandon Jonesd1049182018-03-28 10:02:20 -07004933 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004934 {
4935 return false;
4936 }
4937
Brandon Jonesd1049182018-03-28 10:02:20 -07004938 SetRobustLengthParam(length, writeLength);
4939
Geoff Lang0b031062016-10-13 14:30:04 -04004940 return true;
4941}
4942
Geoff Lang0b031062016-10-13 14:30:04 -04004943bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4944 GLuint index,
4945 GLenum pname,
4946 GLsizei bufSize,
4947 GLsizei *length,
4948 void **pointer)
4949{
4950 if (!ValidateRobustEntryPoint(context, bufSize))
4951 {
4952 return false;
4953 }
4954
Brandon Jonesd1049182018-03-28 10:02:20 -07004955 GLsizei writeLength = 0;
4956
4957 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004958 {
4959 return false;
4960 }
4961
Brandon Jonesd1049182018-03-28 10:02:20 -07004962 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004963 {
4964 return false;
4965 }
4966
Brandon Jonesd1049182018-03-28 10:02:20 -07004967 SetRobustLengthParam(length, writeLength);
4968
Geoff Lang0b031062016-10-13 14:30:04 -04004969 return true;
4970}
4971
Geoff Lang0b031062016-10-13 14:30:04 -04004972bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4973 GLuint index,
4974 GLenum pname,
4975 GLsizei bufSize,
4976 GLsizei *length,
4977 GLint *params)
4978{
4979 if (!ValidateRobustEntryPoint(context, bufSize))
4980 {
4981 return false;
4982 }
4983
Brandon Jonesd1049182018-03-28 10:02:20 -07004984 GLsizei writeLength = 0;
4985
4986 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004987 {
4988 return false;
4989 }
4990
Brandon Jonesd1049182018-03-28 10:02:20 -07004991 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004992 {
4993 return false;
4994 }
4995
Brandon Jonesd1049182018-03-28 10:02:20 -07004996 SetRobustLengthParam(length, writeLength);
4997
Geoff Lang0b031062016-10-13 14:30:04 -04004998 return true;
4999}
5000
Geoff Lang0b031062016-10-13 14:30:04 -04005001bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
5002 GLuint index,
5003 GLenum pname,
5004 GLsizei bufSize,
5005 GLsizei *length,
5006 GLuint *params)
5007{
5008 if (!ValidateRobustEntryPoint(context, bufSize))
5009 {
5010 return false;
5011 }
5012
Brandon Jonesd1049182018-03-28 10:02:20 -07005013 GLsizei writeLength = 0;
5014
5015 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04005016 {
5017 return false;
5018 }
5019
Brandon Jonesd1049182018-03-28 10:02:20 -07005020 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04005021 {
5022 return false;
5023 }
5024
Brandon Jonesd1049182018-03-28 10:02:20 -07005025 SetRobustLengthParam(length, writeLength);
5026
Geoff Lang0b031062016-10-13 14:30:04 -04005027 return true;
5028}
5029
Geoff Lang6899b872016-10-14 11:30:13 -04005030bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5031 GLuint program,
5032 GLuint uniformBlockIndex,
5033 GLenum pname,
5034 GLsizei bufSize,
5035 GLsizei *length,
5036 GLint *params)
5037{
5038 if (!ValidateRobustEntryPoint(context, bufSize))
5039 {
5040 return false;
5041 }
5042
Brandon Jonesd1049182018-03-28 10:02:20 -07005043 GLsizei writeLength = 0;
5044
5045 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5046 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005047 {
5048 return false;
5049 }
5050
Brandon Jonesd1049182018-03-28 10:02:20 -07005051 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005052 {
5053 return false;
5054 }
5055
Brandon Jonesd1049182018-03-28 10:02:20 -07005056 SetRobustLengthParam(length, writeLength);
5057
Geoff Lang6899b872016-10-14 11:30:13 -04005058 return true;
5059}
5060
Brandon Jones416aaf92018-04-10 08:10:16 -07005061bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005062 GLenum target,
5063 GLenum internalformat,
5064 GLenum pname,
5065 GLsizei bufSize,
5066 GLsizei *length,
5067 GLint *params)
5068{
5069 if (!ValidateRobustEntryPoint(context, bufSize))
5070 {
5071 return false;
5072 }
5073
Brandon Jonesd1049182018-03-28 10:02:20 -07005074 GLsizei numParams = 0;
5075
5076 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5077 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005078 {
5079 return false;
5080 }
5081
Brandon Jonesd1049182018-03-28 10:02:20 -07005082 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005083 {
5084 return false;
5085 }
5086
Brandon Jonesd1049182018-03-28 10:02:20 -07005087 SetRobustLengthParam(length, numParams);
5088
Geoff Lang0a9661f2016-10-20 10:59:20 -07005089 return true;
5090}
5091
Jamie Madill5b772312018-03-08 20:28:32 -05005092bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005093 GLuint attribIndex,
5094 GLint size,
5095 GLenum type,
5096 GLboolean pureInteger)
5097{
5098 const Caps &caps = context->getCaps();
5099 if (attribIndex >= caps.maxVertexAttributes)
5100 {
Jamie Madille0472f32018-11-27 16:32:45 -05005101 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005102 return false;
5103 }
5104
5105 if (size < 1 || size > 4)
5106 {
Jamie Madille0472f32018-11-27 16:32:45 -05005107 context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005108 return false;
Shao80957d92017-02-20 21:25:59 +08005109 }
5110
5111 switch (type)
5112 {
5113 case GL_BYTE:
5114 case GL_UNSIGNED_BYTE:
5115 case GL_SHORT:
5116 case GL_UNSIGNED_SHORT:
5117 break;
5118
5119 case GL_INT:
5120 case GL_UNSIGNED_INT:
5121 if (context->getClientMajorVersion() < 3)
5122 {
Jamie Madill610640f2018-11-21 17:28:41 -05005123 context->validationError(GL_INVALID_ENUM,
5124 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005125 return false;
5126 }
5127 break;
5128
5129 case GL_FIXED:
5130 case GL_FLOAT:
5131 if (pureInteger)
5132 {
Jamie Madille0472f32018-11-27 16:32:45 -05005133 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005134 return false;
5135 }
5136 break;
5137
5138 case GL_HALF_FLOAT:
5139 if (context->getClientMajorVersion() < 3)
5140 {
Jamie Madill610640f2018-11-21 17:28:41 -05005141 context->validationError(GL_INVALID_ENUM,
5142 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005143 return false;
5144 }
5145 if (pureInteger)
5146 {
Jamie Madille0472f32018-11-27 16:32:45 -05005147 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005148 return false;
5149 }
5150 break;
5151
5152 case GL_INT_2_10_10_10_REV:
5153 case GL_UNSIGNED_INT_2_10_10_10_REV:
5154 if (context->getClientMajorVersion() < 3)
5155 {
Jamie Madill610640f2018-11-21 17:28:41 -05005156 context->validationError(GL_INVALID_ENUM,
5157 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005158 return false;
5159 }
5160 if (pureInteger)
5161 {
Jamie Madille0472f32018-11-27 16:32:45 -05005162 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005163 return false;
5164 }
5165 if (size != 4)
5166 {
Jamie Madill610640f2018-11-21 17:28:41 -05005167 context->validationError(GL_INVALID_OPERATION,
5168 "Type is INT_2_10_10_10_REV or "
5169 "UNSIGNED_INT_2_10_10_10_REV and "
5170 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005171 return false;
5172 }
5173 break;
5174
5175 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005176 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08005177 return false;
5178 }
5179
5180 return true;
5181}
5182
Geoff Lang76e65652017-03-27 14:58:02 -04005183// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5184// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5185// specified clear value and the type of a buffer that is being cleared generates an
5186// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005187bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005188 GLint drawbuffer,
5189 const GLenum *validComponentTypes,
5190 size_t validComponentTypeCount)
5191{
5192 const FramebufferAttachment *attachment =
5193 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5194 if (attachment)
5195 {
5196 GLenum componentType = attachment->getFormat().info->componentType;
5197 const GLenum *end = validComponentTypes + validComponentTypeCount;
5198 if (std::find(validComponentTypes, end, componentType) == end)
5199 {
Jamie Madill610640f2018-11-21 17:28:41 -05005200 context->validationError(
5201 GL_INVALID_OPERATION,
5202 "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005203 return false;
5204 }
5205 }
5206
5207 return true;
5208}
5209
Jamie Madill5b772312018-03-08 20:28:32 -05005210bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005211{
5212 if (!ValidateRobustEntryPoint(context, dataSize))
5213 {
5214 return false;
5215 }
5216
Jamie Madill43da7c42018-08-01 11:34:49 -04005217 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005218 if (pixelUnpackBuffer == nullptr)
5219 {
5220 if (dataSize < imageSize)
5221 {
Jamie Madill610640f2018-11-21 17:28:41 -05005222 context->validationError(GL_INVALID_OPERATION, "dataSize is too small");
Corentin Wallezb2931602017-04-11 15:58:57 -04005223 }
5224 }
5225 return true;
5226}
5227
Jamie Madill5b772312018-03-08 20:28:32 -05005228bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005229 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005230 GLenum pname,
5231 bool pointerVersion,
5232 GLsizei *numParams)
5233{
5234 if (numParams)
5235 {
5236 *numParams = 0;
5237 }
5238
Corentin Walleze4477002017-12-01 14:39:58 -05005239 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005240 {
Jamie Madille0472f32018-11-27 16:32:45 -05005241 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005242 return false;
5243 }
5244
5245 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5246 if (!buffer)
5247 {
5248 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05005249 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005250 return false;
5251 }
5252
5253 const Extensions &extensions = context->getExtensions();
5254
5255 switch (pname)
5256 {
5257 case GL_BUFFER_USAGE:
5258 case GL_BUFFER_SIZE:
5259 break;
5260
5261 case GL_BUFFER_ACCESS_OES:
5262 if (!extensions.mapBuffer)
5263 {
Jamie Madill610640f2018-11-21 17:28:41 -05005264 context->validationError(GL_INVALID_ENUM,
5265 "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005266 return false;
5267 }
5268 break;
5269
5270 case GL_BUFFER_MAPPED:
5271 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5272 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5273 !extensions.mapBufferRange)
5274 {
Jamie Madill610640f2018-11-21 17:28:41 -05005275 context->validationError(GL_INVALID_ENUM,
5276 "pname requires OpenGL ES 3.0, "
5277 "GL_OES_mapbuffer or "
5278 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005279 return false;
5280 }
5281 break;
5282
5283 case GL_BUFFER_MAP_POINTER:
5284 if (!pointerVersion)
5285 {
Jamie Madill610640f2018-11-21 17:28:41 -05005286 context->validationError(
5287 GL_INVALID_ENUM,
5288 "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005289 return false;
5290 }
5291 break;
5292
5293 case GL_BUFFER_ACCESS_FLAGS:
5294 case GL_BUFFER_MAP_OFFSET:
5295 case GL_BUFFER_MAP_LENGTH:
5296 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5297 {
Jamie Madill610640f2018-11-21 17:28:41 -05005298 context->validationError(
5299 GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005300 return false;
5301 }
5302 break;
5303
Geoff Lang79b91402018-10-04 15:11:30 -04005304 case GL_MEMORY_SIZE_ANGLE:
5305 if (!context->getExtensions().memorySize)
5306 {
Jamie Madille0472f32018-11-27 16:32:45 -05005307 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005308 return false;
5309 }
5310 break;
5311
Jamie Madillbe849e42017-05-02 15:49:00 -04005312 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005313 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005314 return false;
5315 }
5316
5317 // All buffer parameter queries return one value.
5318 if (numParams)
5319 {
5320 *numParams = 1;
5321 }
5322
5323 return true;
5324}
5325
5326bool ValidateGetRenderbufferParameterivBase(Context *context,
5327 GLenum target,
5328 GLenum pname,
5329 GLsizei *length)
5330{
5331 if (length)
5332 {
5333 *length = 0;
5334 }
5335
5336 if (target != GL_RENDERBUFFER)
5337 {
Jamie Madille0472f32018-11-27 16:32:45 -05005338 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005339 return false;
5340 }
5341
5342 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5343 if (renderbuffer == nullptr)
5344 {
Jamie Madille0472f32018-11-27 16:32:45 -05005345 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005346 return false;
5347 }
5348
5349 switch (pname)
5350 {
5351 case GL_RENDERBUFFER_WIDTH:
5352 case GL_RENDERBUFFER_HEIGHT:
5353 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5354 case GL_RENDERBUFFER_RED_SIZE:
5355 case GL_RENDERBUFFER_GREEN_SIZE:
5356 case GL_RENDERBUFFER_BLUE_SIZE:
5357 case GL_RENDERBUFFER_ALPHA_SIZE:
5358 case GL_RENDERBUFFER_DEPTH_SIZE:
5359 case GL_RENDERBUFFER_STENCIL_SIZE:
5360 break;
5361
5362 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5363 if (!context->getExtensions().framebufferMultisample)
5364 {
Jamie Madille0472f32018-11-27 16:32:45 -05005365 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005366 return false;
5367 }
5368 break;
5369
Geoff Lang79b91402018-10-04 15:11:30 -04005370 case GL_MEMORY_SIZE_ANGLE:
5371 if (!context->getExtensions().memorySize)
5372 {
Jamie Madille0472f32018-11-27 16:32:45 -05005373 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005374 return false;
5375 }
5376 break;
5377
Jamie Madillbe849e42017-05-02 15:49:00 -04005378 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005379 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005380 return false;
5381 }
5382
5383 if (length)
5384 {
5385 *length = 1;
5386 }
5387 return true;
5388}
5389
5390bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5391{
5392 if (length)
5393 {
5394 *length = 0;
5395 }
5396
5397 if (GetValidShader(context, shader) == nullptr)
5398 {
5399 return false;
5400 }
5401
5402 switch (pname)
5403 {
5404 case GL_SHADER_TYPE:
5405 case GL_DELETE_STATUS:
5406 case GL_COMPILE_STATUS:
5407 case GL_INFO_LOG_LENGTH:
5408 case GL_SHADER_SOURCE_LENGTH:
5409 break;
5410
5411 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5412 if (!context->getExtensions().translatedShaderSource)
5413 {
Jamie Madille0472f32018-11-27 16:32:45 -05005414 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005415 return false;
5416 }
5417 break;
5418
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005419 case GL_COMPLETION_STATUS_KHR:
5420 if (!context->getExtensions().parallelShaderCompile)
5421 {
Jamie Madille0472f32018-11-27 16:32:45 -05005422 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005423 return false;
5424 }
5425 break;
5426
Jamie Madillbe849e42017-05-02 15:49:00 -04005427 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005428 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005429 return false;
5430 }
5431
5432 if (length)
5433 {
5434 *length = 1;
5435 }
5436 return true;
5437}
5438
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005439bool ValidateGetTexParameterBase(Context *context,
5440 TextureType target,
5441 GLenum pname,
5442 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005443{
5444 if (length)
5445 {
5446 *length = 0;
5447 }
5448
5449 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5450 {
Jamie Madille0472f32018-11-27 16:32:45 -05005451 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005452 return false;
5453 }
5454
5455 if (context->getTargetTexture(target) == nullptr)
5456 {
5457 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005458 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005459 return false;
5460 }
5461
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005462 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5463 {
Jamie Madille0472f32018-11-27 16:32:45 -05005464 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005465 return false;
5466 }
5467
Jamie Madillbe849e42017-05-02 15:49:00 -04005468 switch (pname)
5469 {
5470 case GL_TEXTURE_MAG_FILTER:
5471 case GL_TEXTURE_MIN_FILTER:
5472 case GL_TEXTURE_WRAP_S:
5473 case GL_TEXTURE_WRAP_T:
5474 break;
5475
5476 case GL_TEXTURE_USAGE_ANGLE:
5477 if (!context->getExtensions().textureUsage)
5478 {
Jamie Madille0472f32018-11-27 16:32:45 -05005479 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005480 return false;
5481 }
5482 break;
5483
5484 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005485 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005486 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005487 return false;
5488 }
5489 break;
5490
5491 case GL_TEXTURE_IMMUTABLE_FORMAT:
5492 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5493 {
Jamie Madille0472f32018-11-27 16:32:45 -05005494 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005495 return false;
5496 }
5497 break;
5498
5499 case GL_TEXTURE_WRAP_R:
5500 case GL_TEXTURE_IMMUTABLE_LEVELS:
5501 case GL_TEXTURE_SWIZZLE_R:
5502 case GL_TEXTURE_SWIZZLE_G:
5503 case GL_TEXTURE_SWIZZLE_B:
5504 case GL_TEXTURE_SWIZZLE_A:
5505 case GL_TEXTURE_BASE_LEVEL:
5506 case GL_TEXTURE_MAX_LEVEL:
5507 case GL_TEXTURE_MIN_LOD:
5508 case GL_TEXTURE_MAX_LOD:
5509 case GL_TEXTURE_COMPARE_MODE:
5510 case GL_TEXTURE_COMPARE_FUNC:
5511 if (context->getClientMajorVersion() < 3)
5512 {
Jamie Madill610640f2018-11-21 17:28:41 -05005513 context->validationError(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005514 return false;
5515 }
5516 break;
5517
5518 case GL_TEXTURE_SRGB_DECODE_EXT:
5519 if (!context->getExtensions().textureSRGBDecode)
5520 {
Jamie Madill610640f2018-11-21 17:28:41 -05005521 context->validationError(GL_INVALID_ENUM,
5522 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005523 return false;
5524 }
5525 break;
5526
Yunchao Hebacaa712018-01-30 14:01:39 +08005527 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5528 if (context->getClientVersion() < Version(3, 1))
5529 {
Jamie Madille0472f32018-11-27 16:32:45 -05005530 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005531 return false;
5532 }
5533 break;
5534
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005535 case GL_GENERATE_MIPMAP:
5536 case GL_TEXTURE_CROP_RECT_OES:
5537 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5538 // after GL_OES_draw_texture functionality implemented
5539 if (context->getClientMajorVersion() > 1)
5540 {
Jamie Madille0472f32018-11-27 16:32:45 -05005541 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005542 return false;
5543 }
5544 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005545
5546 case GL_MEMORY_SIZE_ANGLE:
5547 if (!context->getExtensions().memorySize)
5548 {
Jamie Madille0472f32018-11-27 16:32:45 -05005549 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005550 return false;
5551 }
5552 break;
5553
Till Rathmannb8543632018-10-02 19:46:14 +02005554 case GL_TEXTURE_BORDER_COLOR:
5555 if (!context->getExtensions().textureBorderClamp)
5556 {
Jamie Madille0472f32018-11-27 16:32:45 -05005557 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005558 return false;
5559 }
5560 break;
5561
Jamie Madillbe849e42017-05-02 15:49:00 -04005562 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005563 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005564 return false;
5565 }
5566
5567 if (length)
5568 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005569 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005570 }
5571 return true;
5572}
5573
5574bool ValidateGetVertexAttribBase(Context *context,
5575 GLuint index,
5576 GLenum pname,
5577 GLsizei *length,
5578 bool pointer,
5579 bool pureIntegerEntryPoint)
5580{
5581 if (length)
5582 {
5583 *length = 0;
5584 }
5585
5586 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5587 {
Jamie Madill610640f2018-11-21 17:28:41 -05005588 context->validationError(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005589 return false;
5590 }
5591
5592 if (index >= context->getCaps().maxVertexAttributes)
5593 {
Jamie Madille0472f32018-11-27 16:32:45 -05005594 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005595 return false;
5596 }
5597
5598 if (pointer)
5599 {
5600 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5601 {
Jamie Madille0472f32018-11-27 16:32:45 -05005602 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005603 return false;
5604 }
5605 }
5606 else
5607 {
5608 switch (pname)
5609 {
5610 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5611 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5612 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5613 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5614 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5615 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5616 case GL_CURRENT_VERTEX_ATTRIB:
5617 break;
5618
5619 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5620 static_assert(
5621 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5622 "ANGLE extension enums not equal to GL enums.");
5623 if (context->getClientMajorVersion() < 3 &&
5624 !context->getExtensions().instancedArrays)
5625 {
Jamie Madill610640f2018-11-21 17:28:41 -05005626 context->validationError(GL_INVALID_ENUM,
5627 "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5628 "requires OpenGL ES 3.0 or "
5629 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005630 return false;
5631 }
5632 break;
5633
5634 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5635 if (context->getClientMajorVersion() < 3)
5636 {
Jamie Madill610640f2018-11-21 17:28:41 -05005637 context->validationError(
5638 GL_INVALID_ENUM, "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005639 return false;
5640 }
5641 break;
5642
5643 case GL_VERTEX_ATTRIB_BINDING:
5644 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5645 if (context->getClientVersion() < ES_3_1)
5646 {
Jamie Madill610640f2018-11-21 17:28:41 -05005647 context->validationError(GL_INVALID_ENUM,
5648 "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005649 return false;
5650 }
5651 break;
5652
5653 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005654 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005655 return false;
5656 }
5657 }
5658
5659 if (length)
5660 {
5661 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5662 {
5663 *length = 4;
5664 }
5665 else
5666 {
5667 *length = 1;
5668 }
5669 }
5670
5671 return true;
5672}
5673
Jamie Madill4928b7c2017-06-20 12:57:39 -04005674bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005675 GLint x,
5676 GLint y,
5677 GLsizei width,
5678 GLsizei height,
5679 GLenum format,
5680 GLenum type,
5681 GLsizei bufSize,
5682 GLsizei *length,
5683 GLsizei *columns,
5684 GLsizei *rows,
5685 void *pixels)
5686{
5687 if (length != nullptr)
5688 {
5689 *length = 0;
5690 }
5691 if (rows != nullptr)
5692 {
5693 *rows = 0;
5694 }
5695 if (columns != nullptr)
5696 {
5697 *columns = 0;
5698 }
5699
5700 if (width < 0 || height < 0)
5701 {
Jamie Madille0472f32018-11-27 16:32:45 -05005702 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005703 return false;
5704 }
5705
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005706 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005707
Jamie Madill427064d2018-04-13 16:20:34 -04005708 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005709 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005710 return false;
5711 }
5712
Jamie Madille98b1b52018-03-08 09:47:23 -05005713 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005714 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005715 return false;
5716 }
5717
Jamie Madill690c8eb2018-03-12 15:20:03 -04005718 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005719 ASSERT(framebuffer);
5720
5721 if (framebuffer->getReadBufferState() == GL_NONE)
5722 {
Jamie Madille0472f32018-11-27 16:32:45 -05005723 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005724 return false;
5725 }
5726
5727 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5728 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5729 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5730 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5731 // situation is an application error that would lead to a crash in ANGLE.
5732 if (readBuffer == nullptr)
5733 {
Jamie Madille0472f32018-11-27 16:32:45 -05005734 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005735 return false;
5736 }
5737
Martin Radev28031682017-07-28 14:47:56 +03005738 // ANGLE_multiview, Revision 1:
5739 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005740 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5741 // in the current read framebuffer is more than one.
5742 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005743 {
Jamie Madill610640f2018-11-21 17:28:41 -05005744 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
5745 "Attempting to read from a multi-view framebuffer.");
Martin Radev28031682017-07-28 14:47:56 +03005746 return false;
5747 }
5748
Geoff Lang280ba992017-04-18 16:30:58 -04005749 if (context->getExtensions().webglCompatibility)
5750 {
5751 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5752 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5753 // and type before validating the combination of format and type. However, the
5754 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5755 // verifies that GL_INVALID_OPERATION is generated.
5756 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5757 // dEQP/WebGL.
5758 if (!ValidReadPixelsFormatEnum(context, format))
5759 {
Jamie Madille0472f32018-11-27 16:32:45 -05005760 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005761 return false;
5762 }
5763
5764 if (!ValidReadPixelsTypeEnum(context, type))
5765 {
Jamie Madille0472f32018-11-27 16:32:45 -05005766 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005767 return false;
5768 }
5769 }
5770
Jamie Madill690c8eb2018-03-12 15:20:03 -04005771 GLenum currentFormat = GL_NONE;
5772 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5773
5774 GLenum currentType = GL_NONE;
5775 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5776
Jamie Madillbe849e42017-05-02 15:49:00 -04005777 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5778
5779 bool validFormatTypeCombination =
5780 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5781
5782 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5783 {
Jamie Madille0472f32018-11-27 16:32:45 -05005784 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005785 return false;
5786 }
5787
5788 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005789 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005790 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5791 {
5792 // ...the buffer object's data store is currently mapped.
Jamie Madill610640f2018-11-21 17:28:41 -05005793 context->validationError(GL_INVALID_OPERATION, "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005794 return false;
5795 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005796 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5797 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5798 {
Jamie Madille0472f32018-11-27 16:32:45 -05005799 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005800 return false;
5801 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005802
5803 // .. the data would be packed to the buffer object such that the memory writes required
5804 // would exceed the data store size.
5805 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005806 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005807 const auto &pack = context->getGLState().getPackState();
5808
Jamie Madillca2ff382018-07-11 09:01:17 -04005809 GLuint endByte = 0;
5810 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005811 {
Jamie Madille0472f32018-11-27 16:32:45 -05005812 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005813 return false;
5814 }
5815
Jamie Madillbe849e42017-05-02 15:49:00 -04005816 if (bufSize >= 0)
5817 {
5818 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5819 {
Jamie Madille0472f32018-11-27 16:32:45 -05005820 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005821 return false;
5822 }
5823 }
5824
5825 if (pixelPackBuffer != nullptr)
5826 {
5827 CheckedNumeric<size_t> checkedEndByte(endByte);
5828 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5829 checkedEndByte += checkedOffset;
5830
5831 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5832 {
5833 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005834 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 return false;
5836 }
5837 }
5838
5839 if (pixelPackBuffer == nullptr && length != nullptr)
5840 {
5841 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5842 {
Jamie Madille0472f32018-11-27 16:32:45 -05005843 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005844 return false;
5845 }
5846
5847 *length = static_cast<GLsizei>(endByte);
5848 }
5849
Geoff Langa953b522018-02-21 16:56:23 -05005850 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005851 angle::CheckedNumeric<int> clippedExtent(length);
5852 if (start < 0)
5853 {
5854 // "subtract" the area that is less than 0
5855 clippedExtent += start;
5856 }
5857
Geoff Langa953b522018-02-21 16:56:23 -05005858 angle::CheckedNumeric<int> readExtent = start;
5859 readExtent += length;
5860 if (!readExtent.IsValid())
5861 {
5862 return false;
5863 }
5864
5865 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005866 {
5867 // Subtract the region to the right of the read buffer
5868 clippedExtent -= (readExtent - bufferSize);
5869 }
5870
5871 if (!clippedExtent.IsValid())
5872 {
Geoff Langa953b522018-02-21 16:56:23 -05005873 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 }
5875
Geoff Langa953b522018-02-21 16:56:23 -05005876 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5877 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005878 };
5879
Geoff Langa953b522018-02-21 16:56:23 -05005880 GLsizei writtenColumns = 0;
5881 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5882 {
Jamie Madille0472f32018-11-27 16:32:45 -05005883 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005884 return false;
5885 }
5886
5887 GLsizei writtenRows = 0;
5888 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5889 {
Jamie Madille0472f32018-11-27 16:32:45 -05005890 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005891 return false;
5892 }
5893
Jamie Madillbe849e42017-05-02 15:49:00 -04005894 if (columns != nullptr)
5895 {
Geoff Langa953b522018-02-21 16:56:23 -05005896 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005897 }
5898
5899 if (rows != nullptr)
5900 {
Geoff Langa953b522018-02-21 16:56:23 -05005901 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005902 }
5903
5904 return true;
5905}
5906
5907template <typename ParamType>
5908bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005909 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 GLenum pname,
5911 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005912 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005913 const ParamType *params)
5914{
5915 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5916 {
Jamie Madille0472f32018-11-27 16:32:45 -05005917 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 return false;
5919 }
5920
5921 if (context->getTargetTexture(target) == nullptr)
5922 {
5923 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005924 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005925 return false;
5926 }
5927
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005928 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 if (bufSize >= 0 && bufSize < minBufSize)
5930 {
Jamie Madille0472f32018-11-27 16:32:45 -05005931 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005932 return false;
5933 }
5934
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005935 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5936 {
Jamie Madille0472f32018-11-27 16:32:45 -05005937 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005938 return false;
5939 }
5940
Jamie Madillbe849e42017-05-02 15:49:00 -04005941 switch (pname)
5942 {
5943 case GL_TEXTURE_WRAP_R:
5944 case GL_TEXTURE_SWIZZLE_R:
5945 case GL_TEXTURE_SWIZZLE_G:
5946 case GL_TEXTURE_SWIZZLE_B:
5947 case GL_TEXTURE_SWIZZLE_A:
5948 case GL_TEXTURE_BASE_LEVEL:
5949 case GL_TEXTURE_MAX_LEVEL:
5950 case GL_TEXTURE_COMPARE_MODE:
5951 case GL_TEXTURE_COMPARE_FUNC:
5952 case GL_TEXTURE_MIN_LOD:
5953 case GL_TEXTURE_MAX_LOD:
5954 if (context->getClientMajorVersion() < 3)
5955 {
Jamie Madille0472f32018-11-27 16:32:45 -05005956 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005957 return false;
5958 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005959 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005960 {
Jamie Madill610640f2018-11-21 17:28:41 -05005961 context->validationError(GL_INVALID_ENUM,
5962 "ES3 texture parameters are not "
5963 "available without "
5964 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 return false;
5966 }
5967 break;
5968
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005969 case GL_GENERATE_MIPMAP:
5970 case GL_TEXTURE_CROP_RECT_OES:
5971 if (context->getClientMajorVersion() > 1)
5972 {
Jamie Madille0472f32018-11-27 16:32:45 -05005973 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005974 return false;
5975 }
5976 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 default:
5978 break;
5979 }
5980
Olli Etuahod310a432018-08-24 15:40:23 +03005981 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005982 {
5983 switch (pname)
5984 {
5985 case GL_TEXTURE_MIN_FILTER:
5986 case GL_TEXTURE_MAG_FILTER:
5987 case GL_TEXTURE_WRAP_S:
5988 case GL_TEXTURE_WRAP_T:
5989 case GL_TEXTURE_WRAP_R:
5990 case GL_TEXTURE_MIN_LOD:
5991 case GL_TEXTURE_MAX_LOD:
5992 case GL_TEXTURE_COMPARE_MODE:
5993 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005994 case GL_TEXTURE_BORDER_COLOR:
Jamie Madill610640f2018-11-21 17:28:41 -05005995 context->validationError(GL_INVALID_ENUM,
5996 "Invalid parameter for 2D multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08005997 return false;
5998 }
5999 }
6000
Jamie Madillbe849e42017-05-02 15:49:00 -04006001 switch (pname)
6002 {
6003 case GL_TEXTURE_WRAP_S:
6004 case GL_TEXTURE_WRAP_T:
6005 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006006 {
6007 bool restrictedWrapModes =
6008 target == TextureType::External || target == TextureType::Rectangle;
6009 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006011 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006013 }
6014 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006015
6016 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006017 {
6018 bool restrictedMinFilter =
6019 target == TextureType::External || target == TextureType::Rectangle;
6020 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006022 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006024 }
6025 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006026
6027 case GL_TEXTURE_MAG_FILTER:
6028 if (!ValidateTextureMagFilterValue(context, params))
6029 {
6030 return false;
6031 }
6032 break;
6033
6034 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04006035 if (!context->getExtensions().textureUsage)
6036 {
Jamie Madille0472f32018-11-27 16:32:45 -05006037 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04006038 return false;
6039 }
6040
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 switch (ConvertToGLenum(params[0]))
6042 {
6043 case GL_NONE:
6044 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
6045 break;
6046
6047 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006048 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 return false;
6050 }
6051 break;
6052
6053 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006054 {
6055 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6056 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006058 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006060 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
6061 }
6062 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006063
6064 case GL_TEXTURE_MIN_LOD:
6065 case GL_TEXTURE_MAX_LOD:
6066 // any value is permissible
6067 break;
6068
6069 case GL_TEXTURE_COMPARE_MODE:
6070 if (!ValidateTextureCompareModeValue(context, params))
6071 {
6072 return false;
6073 }
6074 break;
6075
6076 case GL_TEXTURE_COMPARE_FUNC:
6077 if (!ValidateTextureCompareFuncValue(context, params))
6078 {
6079 return false;
6080 }
6081 break;
6082
6083 case GL_TEXTURE_SWIZZLE_R:
6084 case GL_TEXTURE_SWIZZLE_G:
6085 case GL_TEXTURE_SWIZZLE_B:
6086 case GL_TEXTURE_SWIZZLE_A:
6087 switch (ConvertToGLenum(params[0]))
6088 {
6089 case GL_RED:
6090 case GL_GREEN:
6091 case GL_BLUE:
6092 case GL_ALPHA:
6093 case GL_ZERO:
6094 case GL_ONE:
6095 break;
6096
6097 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006098 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
6101 break;
6102
6103 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006104 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006105 {
Jamie Madill610640f2018-11-21 17:28:41 -05006106 context->validationError(GL_INVALID_VALUE, "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 return false;
6108 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006109 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 {
Jamie Madill610640f2018-11-21 17:28:41 -05006111 context->validationError(GL_INVALID_OPERATION,
6112 "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006113 return false;
6114 }
Olli Etuahod310a432018-08-24 15:40:23 +03006115 if ((target == TextureType::_2DMultisample ||
6116 target == TextureType::_2DMultisampleArray) &&
6117 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006118 {
Jamie Madill610640f2018-11-21 17:28:41 -05006119 context->validationError(GL_INVALID_OPERATION,
6120 "Base level must be 0 for multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08006121 return false;
6122 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006123 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006124 {
Jamie Madill610640f2018-11-21 17:28:41 -05006125 context->validationError(GL_INVALID_OPERATION,
6126 "Base level must be 0 for rectangle textures.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006127 return false;
6128 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 break;
6130
6131 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006132 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006133 {
Jamie Madille0472f32018-11-27 16:32:45 -05006134 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006135 return false;
6136 }
6137 break;
6138
6139 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6140 if (context->getClientVersion() < Version(3, 1))
6141 {
Jamie Madille0472f32018-11-27 16:32:45 -05006142 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 return false;
6144 }
6145 switch (ConvertToGLenum(params[0]))
6146 {
6147 case GL_DEPTH_COMPONENT:
6148 case GL_STENCIL_INDEX:
6149 break;
6150
6151 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006152 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 return false;
6154 }
6155 break;
6156
6157 case GL_TEXTURE_SRGB_DECODE_EXT:
6158 if (!ValidateTextureSRGBDecodeValue(context, params))
6159 {
6160 return false;
6161 }
6162 break;
6163
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006164 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006165 if (context->getClientMajorVersion() > 1)
6166 {
Jamie Madille0472f32018-11-27 16:32:45 -05006167 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006168 return false;
6169 }
6170 break;
Till Rathmannb8543632018-10-02 19:46:14 +02006171
6172 case GL_TEXTURE_CROP_RECT_OES:
6173 if (context->getClientMajorVersion() > 1)
6174 {
Jamie Madille0472f32018-11-27 16:32:45 -05006175 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02006176 return false;
6177 }
6178 if (!vectorParams)
6179 {
Jamie Madille0472f32018-11-27 16:32:45 -05006180 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006181 return false;
6182 }
6183 break;
6184
6185 case GL_TEXTURE_BORDER_COLOR:
6186 if (!context->getExtensions().textureBorderClamp)
6187 {
Jamie Madille0472f32018-11-27 16:32:45 -05006188 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006189 return false;
6190 }
6191 if (!vectorParams)
6192 {
Jamie Madille0472f32018-11-27 16:32:45 -05006193 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006194 return false;
6195 }
6196 break;
6197
Jamie Madillbe849e42017-05-02 15:49:00 -04006198 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006199 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006200 return false;
6201 }
6202
6203 return true;
6204}
6205
Till Rathmannb8543632018-10-02 19:46:14 +02006206template bool ValidateTexParameterBase(Context *,
6207 TextureType,
6208 GLenum,
6209 GLsizei,
6210 bool,
6211 const GLfloat *);
6212template bool ValidateTexParameterBase(Context *,
6213 TextureType,
6214 GLenum,
6215 GLsizei,
6216 bool,
6217 const GLint *);
6218template bool ValidateTexParameterBase(Context *,
6219 TextureType,
6220 GLenum,
6221 GLsizei,
6222 bool,
6223 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006224
Jamie Madill5b772312018-03-08 20:28:32 -05006225bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006226{
6227 if (index >= MAX_VERTEX_ATTRIBS)
6228 {
Jamie Madille0472f32018-11-27 16:32:45 -05006229 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04006230 return false;
6231 }
6232
6233 return true;
6234}
6235
6236bool ValidateGetActiveUniformBlockivBase(Context *context,
6237 GLuint program,
6238 GLuint uniformBlockIndex,
6239 GLenum pname,
6240 GLsizei *length)
6241{
6242 if (length)
6243 {
6244 *length = 0;
6245 }
6246
6247 if (context->getClientMajorVersion() < 3)
6248 {
Jamie Madille0472f32018-11-27 16:32:45 -05006249 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04006250 return false;
6251 }
6252
6253 Program *programObject = GetValidProgram(context, program);
6254 if (!programObject)
6255 {
6256 return false;
6257 }
6258
6259 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6260 {
Jamie Madill610640f2018-11-21 17:28:41 -05006261 context->validationError(GL_INVALID_VALUE,
6262 "uniformBlockIndex exceeds active uniform block count.");
Jamie Madill12e957f2017-08-26 21:42:26 -04006263 return false;
6264 }
6265
6266 switch (pname)
6267 {
6268 case GL_UNIFORM_BLOCK_BINDING:
6269 case GL_UNIFORM_BLOCK_DATA_SIZE:
6270 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6271 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6272 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6273 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6274 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6275 break;
6276
6277 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006278 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04006279 return false;
6280 }
6281
6282 if (length)
6283 {
6284 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6285 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006286 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006287 programObject->getUniformBlockByIndex(uniformBlockIndex);
6288 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6289 }
6290 else
6291 {
6292 *length = 1;
6293 }
6294 }
6295
6296 return true;
6297}
6298
Jamie Madill9696d072017-08-26 23:19:57 -04006299template <typename ParamType>
6300bool ValidateSamplerParameterBase(Context *context,
6301 GLuint sampler,
6302 GLenum pname,
6303 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02006304 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04006305 ParamType *params)
6306{
6307 if (context->getClientMajorVersion() < 3)
6308 {
Jamie Madille0472f32018-11-27 16:32:45 -05006309 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006310 return false;
6311 }
6312
6313 if (!context->isSampler(sampler))
6314 {
Jamie Madille0472f32018-11-27 16:32:45 -05006315 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006316 return false;
6317 }
6318
Till Rathmannb8543632018-10-02 19:46:14 +02006319 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006320 if (bufSize >= 0 && bufSize < minBufSize)
6321 {
Jamie Madille0472f32018-11-27 16:32:45 -05006322 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006323 return false;
6324 }
6325
6326 switch (pname)
6327 {
6328 case GL_TEXTURE_WRAP_S:
6329 case GL_TEXTURE_WRAP_T:
6330 case GL_TEXTURE_WRAP_R:
6331 if (!ValidateTextureWrapModeValue(context, params, false))
6332 {
6333 return false;
6334 }
6335 break;
6336
6337 case GL_TEXTURE_MIN_FILTER:
6338 if (!ValidateTextureMinFilterValue(context, params, false))
6339 {
6340 return false;
6341 }
6342 break;
6343
6344 case GL_TEXTURE_MAG_FILTER:
6345 if (!ValidateTextureMagFilterValue(context, params))
6346 {
6347 return false;
6348 }
6349 break;
6350
6351 case GL_TEXTURE_MIN_LOD:
6352 case GL_TEXTURE_MAX_LOD:
6353 // any value is permissible
6354 break;
6355
6356 case GL_TEXTURE_COMPARE_MODE:
6357 if (!ValidateTextureCompareModeValue(context, params))
6358 {
6359 return false;
6360 }
6361 break;
6362
6363 case GL_TEXTURE_COMPARE_FUNC:
6364 if (!ValidateTextureCompareFuncValue(context, params))
6365 {
6366 return false;
6367 }
6368 break;
6369
6370 case GL_TEXTURE_SRGB_DECODE_EXT:
6371 if (!ValidateTextureSRGBDecodeValue(context, params))
6372 {
6373 return false;
6374 }
6375 break;
6376
Luc Ferron1b1a8642018-01-23 15:12:01 -05006377 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6378 {
6379 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6380 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6381 {
6382 return false;
6383 }
6384 }
6385 break;
6386
Till Rathmannb8543632018-10-02 19:46:14 +02006387 case GL_TEXTURE_BORDER_COLOR:
6388 if (!context->getExtensions().textureBorderClamp)
6389 {
Jamie Madille0472f32018-11-27 16:32:45 -05006390 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006391 return false;
6392 }
6393 if (!vectorParams)
6394 {
Jamie Madille0472f32018-11-27 16:32:45 -05006395 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006396 return false;
6397 }
6398 break;
6399
Jamie Madill9696d072017-08-26 23:19:57 -04006400 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006401 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006402 return false;
6403 }
6404
6405 return true;
6406}
6407
Till Rathmannb8543632018-10-02 19:46:14 +02006408template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6409template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6410template bool ValidateSamplerParameterBase(Context *,
6411 GLuint,
6412 GLenum,
6413 GLsizei,
6414 bool,
6415 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006416
6417bool ValidateGetSamplerParameterBase(Context *context,
6418 GLuint sampler,
6419 GLenum pname,
6420 GLsizei *length)
6421{
6422 if (length)
6423 {
6424 *length = 0;
6425 }
6426
6427 if (context->getClientMajorVersion() < 3)
6428 {
Jamie Madille0472f32018-11-27 16:32:45 -05006429 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006430 return false;
6431 }
6432
6433 if (!context->isSampler(sampler))
6434 {
Jamie Madille0472f32018-11-27 16:32:45 -05006435 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006436 return false;
6437 }
6438
6439 switch (pname)
6440 {
6441 case GL_TEXTURE_WRAP_S:
6442 case GL_TEXTURE_WRAP_T:
6443 case GL_TEXTURE_WRAP_R:
6444 case GL_TEXTURE_MIN_FILTER:
6445 case GL_TEXTURE_MAG_FILTER:
6446 case GL_TEXTURE_MIN_LOD:
6447 case GL_TEXTURE_MAX_LOD:
6448 case GL_TEXTURE_COMPARE_MODE:
6449 case GL_TEXTURE_COMPARE_FUNC:
6450 break;
6451
Luc Ferron1b1a8642018-01-23 15:12:01 -05006452 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6453 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6454 {
6455 return false;
6456 }
6457 break;
6458
Jamie Madill9696d072017-08-26 23:19:57 -04006459 case GL_TEXTURE_SRGB_DECODE_EXT:
6460 if (!context->getExtensions().textureSRGBDecode)
6461 {
Jamie Madill610640f2018-11-21 17:28:41 -05006462 context->validationError(GL_INVALID_ENUM,
6463 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madill9696d072017-08-26 23:19:57 -04006464 return false;
6465 }
6466 break;
6467
Till Rathmannb8543632018-10-02 19:46:14 +02006468 case GL_TEXTURE_BORDER_COLOR:
6469 if (!context->getExtensions().textureBorderClamp)
6470 {
Jamie Madille0472f32018-11-27 16:32:45 -05006471 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006472 return false;
6473 }
6474 break;
6475
Jamie Madill9696d072017-08-26 23:19:57 -04006476 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006477 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006478 return false;
6479 }
6480
6481 if (length)
6482 {
Till Rathmannb8543632018-10-02 19:46:14 +02006483 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006484 }
6485 return true;
6486}
6487
6488bool ValidateGetInternalFormativBase(Context *context,
6489 GLenum target,
6490 GLenum internalformat,
6491 GLenum pname,
6492 GLsizei bufSize,
6493 GLsizei *numParams)
6494{
6495 if (numParams)
6496 {
6497 *numParams = 0;
6498 }
6499
6500 if (context->getClientMajorVersion() < 3)
6501 {
Jamie Madille0472f32018-11-27 16:32:45 -05006502 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006503 return false;
6504 }
6505
6506 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006507 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006508 {
Jamie Madill610640f2018-11-21 17:28:41 -05006509 context->validationError(GL_INVALID_ENUM, "Internal format is not renderable.");
Jamie Madill9696d072017-08-26 23:19:57 -04006510 return false;
6511 }
6512
6513 switch (target)
6514 {
6515 case GL_RENDERBUFFER:
6516 break;
6517
6518 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006519 if (context->getClientVersion() < ES_3_1 &&
6520 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006521 {
Jamie Madill610640f2018-11-21 17:28:41 -05006522 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006523 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006524 return false;
6525 }
6526 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006527 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6528 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006529 {
Jamie Madille0472f32018-11-27 16:32:45 -05006530 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006531 return false;
6532 }
6533 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006534 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006535 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006536 return false;
6537 }
6538
6539 if (bufSize < 0)
6540 {
Jamie Madille0472f32018-11-27 16:32:45 -05006541 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006542 return false;
6543 }
6544
6545 GLsizei maxWriteParams = 0;
6546 switch (pname)
6547 {
6548 case GL_NUM_SAMPLE_COUNTS:
6549 maxWriteParams = 1;
6550 break;
6551
6552 case GL_SAMPLES:
6553 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6554 break;
6555
6556 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006557 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006558 return false;
6559 }
6560
6561 if (numParams)
6562 {
6563 // glGetInternalFormativ will not overflow bufSize
6564 *numParams = std::min(bufSize, maxWriteParams);
6565 }
6566
6567 return true;
6568}
6569
Jamie Madille98b1b52018-03-08 09:47:23 -05006570bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6571{
Jamie Madill427064d2018-04-13 16:20:34 -04006572 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006573 {
Jamie Madille0472f32018-11-27 16:32:45 -05006574 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006575 return false;
6576 }
6577 return true;
6578}
6579
Lingfeng Yang038dd532018-03-29 17:31:52 -07006580bool ValidateMultitextureUnit(Context *context, GLenum texture)
6581{
6582 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6583 {
Jamie Madille0472f32018-11-27 16:32:45 -05006584 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006585 return false;
6586 }
6587 return true;
6588}
6589
Olli Etuahod310a432018-08-24 15:40:23 +03006590bool ValidateTexStorageMultisample(Context *context,
6591 TextureType target,
6592 GLsizei samples,
6593 GLint internalFormat,
6594 GLsizei width,
6595 GLsizei height)
6596{
6597 const Caps &caps = context->getCaps();
6598 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6599 static_cast<GLuint>(height) > caps.max2DTextureSize)
6600 {
Jamie Madille0472f32018-11-27 16:32:45 -05006601 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006602 return false;
6603 }
6604
6605 if (samples == 0)
6606 {
Jamie Madille0472f32018-11-27 16:32:45 -05006607 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006608 return false;
6609 }
6610
6611 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6612 if (!formatCaps.textureAttachment)
6613 {
Jamie Madille0472f32018-11-27 16:32:45 -05006614 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006615 return false;
6616 }
6617
6618 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6619 // is one of the unsized base internalformats listed in table 8.11.
6620 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6621 if (formatInfo.internalFormat == GL_NONE)
6622 {
Jamie Madille0472f32018-11-27 16:32:45 -05006623 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006624 return false;
6625 }
6626
6627 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6628 {
Jamie Madille0472f32018-11-27 16:32:45 -05006629 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006630 return false;
6631 }
6632
6633 Texture *texture = context->getTargetTexture(target);
6634 if (!texture || texture->id() == 0)
6635 {
Jamie Madille0472f32018-11-27 16:32:45 -05006636 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006637 return false;
6638 }
6639
6640 if (texture->getImmutableFormat())
6641 {
Jamie Madille0472f32018-11-27 16:32:45 -05006642 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006643 return false;
6644 }
6645 return true;
6646}
6647
Yizhou Jiang7818a852018-09-06 15:02:04 +08006648bool ValidateTexStorage2DMultisampleBase(Context *context,
6649 TextureType target,
6650 GLsizei samples,
6651 GLint internalFormat,
6652 GLsizei width,
6653 GLsizei height)
6654{
6655 if (target != TextureType::_2DMultisample)
6656 {
Jamie Madille0472f32018-11-27 16:32:45 -05006657 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006658 return false;
6659 }
6660
6661 if (width < 1 || height < 1)
6662 {
Jamie Madille0472f32018-11-27 16:32:45 -05006663 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006664 return false;
6665 }
6666
6667 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6668}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006669
6670bool ValidateGetTexLevelParameterBase(Context *context,
6671 TextureTarget target,
6672 GLint level,
6673 GLenum pname,
6674 GLsizei *length)
6675{
6676
6677 if (length)
6678 {
6679 *length = 0;
6680 }
6681
6682 TextureType type = TextureTargetToType(target);
6683
6684 if (!ValidTexLevelDestinationTarget(context, type))
6685 {
Jamie Madille0472f32018-11-27 16:32:45 -05006686 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006687 return false;
6688 }
6689
6690 if (context->getTargetTexture(type) == nullptr)
6691 {
Jamie Madill610640f2018-11-21 17:28:41 -05006692 context->validationError(GL_INVALID_ENUM, "No texture bound.");
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006693 return false;
6694 }
6695
6696 if (!ValidMipLevel(context, type, level))
6697 {
Jamie Madille0472f32018-11-27 16:32:45 -05006698 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006699 return false;
6700 }
6701
6702 switch (pname)
6703 {
6704 case GL_TEXTURE_RED_TYPE:
6705 case GL_TEXTURE_GREEN_TYPE:
6706 case GL_TEXTURE_BLUE_TYPE:
6707 case GL_TEXTURE_ALPHA_TYPE:
6708 case GL_TEXTURE_DEPTH_TYPE:
6709 break;
6710 case GL_TEXTURE_RED_SIZE:
6711 case GL_TEXTURE_GREEN_SIZE:
6712 case GL_TEXTURE_BLUE_SIZE:
6713 case GL_TEXTURE_ALPHA_SIZE:
6714 case GL_TEXTURE_DEPTH_SIZE:
6715 case GL_TEXTURE_STENCIL_SIZE:
6716 case GL_TEXTURE_SHARED_SIZE:
6717 break;
6718 case GL_TEXTURE_INTERNAL_FORMAT:
6719 case GL_TEXTURE_WIDTH:
6720 case GL_TEXTURE_HEIGHT:
6721 case GL_TEXTURE_DEPTH:
6722 break;
6723 case GL_TEXTURE_SAMPLES:
6724 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6725 break;
6726 case GL_TEXTURE_COMPRESSED:
6727 break;
6728 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006729 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006730 return false;
6731 }
6732
6733 if (length)
6734 {
6735 *length = 1;
6736 }
6737 return true;
6738}
Jamie Madillc29968b2016-01-20 11:17:23 -05006739} // namespace gl