blob: b1e6277589bd333ac1fedb170fa16f30b43e7ec5 [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,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500636 DrawElementsType type,
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 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;
Geoff Langbe607ad2018-11-29 10:14:22 -0500763
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800764 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800765 maxDimension = caps.maxCubeMapTextureSize;
766 break;
Geoff Langbe607ad2018-11-29 10:14:22 -0500767
768 case TextureType::External:
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800769 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400770 return level == 0;
Geoff Langbe607ad2018-11-29 10:14:22 -0500771
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800772 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800773 maxDimension = caps.max3DTextureSize;
774 break;
Geoff Langbe607ad2018-11-29 10:14:22 -0500775
He Yunchaoced53ae2016-11-29 15:00:51 +0800776 default:
777 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400778 }
779
Jamie Madill43da7c42018-08-01 11:34:49 -0400780 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400781}
782
Jamie Madill5b772312018-03-08 20:28:32 -0500783bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800784 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700785 GLint level,
786 GLsizei width,
787 GLsizei height,
788 GLsizei depth,
789 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400790{
Brandon Jones6cad5662017-06-14 13:25:13 -0700791 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400792 {
Jamie Madille0472f32018-11-27 16:32:45 -0500793 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400794 return false;
795 }
Austin Kinross08528e12015-10-07 16:24:40 -0700796 // TexSubImage parameters can be NPOT without textureNPOT extension,
797 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500798 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500799 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500800 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400801 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400802 {
Jamie Madille0472f32018-11-27 16:32:45 -0500803 context->validationError(GL_INVALID_VALUE, kTextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400804 return false;
805 }
806
807 if (!ValidMipLevel(context, target, level))
808 {
Jamie Madille0472f32018-11-27 16:32:45 -0500809 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400810 return false;
811 }
812
813 return true;
814}
815
Geoff Lang966c9402017-04-18 12:38:27 -0400816bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
817{
818 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
819 (size % blockSize == 0);
820}
821
Jamie Madill5b772312018-03-08 20:28:32 -0500822bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500823 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400824 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500825 GLsizei width,
826 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400827{
Jamie Madill43da7c42018-08-01 11:34:49 -0400828 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400829 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400830 {
831 return false;
832 }
833
Geoff Lang966c9402017-04-18 12:38:27 -0400834 if (width < 0 || height < 0)
835 {
836 return false;
837 }
838
839 if (CompressedTextureFormatRequiresExactSize(internalFormat))
840 {
841 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
842 // block size for level 0 but WebGL disallows this.
843 bool smallerThanBlockSizeAllowed =
844 level > 0 || !context->getExtensions().webglCompatibility;
845
846 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
847 smallerThanBlockSizeAllowed) ||
848 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
849 smallerThanBlockSizeAllowed))
850 {
851 return false;
852 }
853 }
854
855 return true;
856}
857
Jamie Madill5b772312018-03-08 20:28:32 -0500858bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400859 GLenum internalFormat,
860 GLint xoffset,
861 GLint yoffset,
862 GLsizei width,
863 GLsizei height,
864 size_t textureWidth,
865 size_t textureHeight)
866{
Jamie Madill43da7c42018-08-01 11:34:49 -0400867 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400868 if (!formatInfo.compressed)
869 {
870 return false;
871 }
872
Geoff Lang44ff5a72017-02-03 15:15:43 -0500873 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400874 {
875 return false;
876 }
877
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500878 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400879 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500880 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400881 yoffset % formatInfo.compressedBlockHeight != 0)
882 {
883 return false;
884 }
885
886 // Allowed to either have data that is a multiple of block size or is smaller than the block
887 // size but fills the entire mip
888 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
889 static_cast<size_t>(width) == textureWidth &&
890 static_cast<size_t>(height) == textureHeight;
891 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
892 (height % formatInfo.compressedBlockHeight) == 0;
893 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400894 {
895 return false;
896 }
897 }
898
Geoff Langd4f180b2013-09-24 13:57:44 -0400899 return true;
900}
901
Jamie Madill5b772312018-03-08 20:28:32 -0500902bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800903 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400904 GLsizei width,
905 GLsizei height,
906 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400907 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400908 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400909 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400910 GLsizei imageSize)
911{
Jamie Madill43da7c42018-08-01 11:34:49 -0400912 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400913 if (pixelUnpackBuffer == nullptr && imageSize < 0)
914 {
915 // Checks are not required
916 return true;
917 }
918
919 // ...the data would be unpacked from the buffer object such that the memory reads required
920 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400921 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400922 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400923 const Extents size(width, height, depth);
Geoff Langff5b2d52016-09-07 11:32:23 -0400924 const auto &unpack = context->getGLState().getUnpackState();
925
Jamie Madill7f232932018-09-12 11:03:06 -0400926 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
927 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400928 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400929 {
Jamie Madille0472f32018-11-27 16:32:45 -0500930 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400931 return false;
932 }
933
Geoff Langff5b2d52016-09-07 11:32:23 -0400934 if (pixelUnpackBuffer)
935 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400936 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400937 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
938 checkedEndByte += checkedOffset;
939
940 if (!checkedEndByte.IsValid() ||
941 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
942 {
943 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -0500944 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400945 return false;
946 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800947 if (context->getExtensions().webglCompatibility &&
948 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
949 {
Jamie Madill610640f2018-11-21 17:28:41 -0500950 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -0500951 kPixelUnpackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -0800952 return false;
953 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400954 }
955 else
956 {
957 ASSERT(imageSize >= 0);
958 if (pixels == nullptr && imageSize != 0)
959 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500960 context->validationError(GL_INVALID_OPERATION, kImageSizeMustBeZero);
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400961 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400962 }
963
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400964 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400965 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500966 context->validationError(GL_INVALID_OPERATION, kImageSizeTooSmall);
Geoff Langff5b2d52016-09-07 11:32:23 -0400967 return false;
968 }
969 }
970
971 return true;
972}
973
Corentin Wallezad3ae902018-03-09 13:40:42 -0500974bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500975{
Geoff Lang37dde692014-01-31 16:34:54 -0500976 switch (queryType)
977 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500978 case QueryType::AnySamples:
979 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400980 return context->getClientMajorVersion() >= 3 ||
981 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500982 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800983 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500984 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800985 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500986 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800987 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500988 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800989 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800990 default:
991 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500992 }
993}
994
Jamie Madill5b772312018-03-08 20:28:32 -0500995bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400996 GLenum type,
997 GLboolean normalized,
998 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400999 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -04001000 bool pureInteger)
1001{
1002 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001003 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
1004 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
1005 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
1006 // parameter exceeds 255.
1007 constexpr GLsizei kMaxWebGLStride = 255;
1008 if (stride > kMaxWebGLStride)
1009 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001010 context->validationError(GL_INVALID_VALUE, kStrideExceedsWebGLLimit);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001011 return false;
1012 }
1013
1014 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1015 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1016 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1017 // or an INVALID_OPERATION error is generated.
Frank Henigmand633b152018-10-04 23:34:31 -04001018 angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1019 size_t typeSize = GetVertexFormatSize(internalType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001020
1021 ASSERT(isPow2(typeSize) && typeSize > 0);
1022 size_t sizeMask = (typeSize - 1);
1023 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1024 {
Jamie Madille0472f32018-11-27 16:32:45 -05001025 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001026 return false;
1027 }
1028
1029 if ((stride & sizeMask) != 0)
1030 {
Jamie Madille0472f32018-11-27 16:32:45 -05001031 context->validationError(GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001032 return false;
1033 }
1034
1035 return true;
1036}
1037
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001038Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001039{
He Yunchaoced53ae2016-11-29 15:00:51 +08001040 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1041 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1042 // or program object and INVALID_OPERATION if the provided name identifies an object
1043 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001044
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001045 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001046
1047 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001048 {
Dian Xiang769769a2015-09-09 15:20:08 -07001049 if (context->getShader(id))
1050 {
Jamie Madille0472f32018-11-27 16:32:45 -05001051 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001052 }
1053 else
1054 {
Jamie Madille0472f32018-11-27 16:32:45 -05001055 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001056 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001057 }
Dian Xiang769769a2015-09-09 15:20:08 -07001058
1059 return validProgram;
1060}
1061
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001062Program *GetValidProgram(Context *context, GLuint id)
1063{
1064 Program *program = GetValidProgramNoResolve(context, id);
1065 if (program)
1066 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001067 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001068 }
1069 return program;
1070}
1071
Jamie Madill5b772312018-03-08 20:28:32 -05001072Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001073{
1074 // See ValidProgram for spec details.
1075
1076 Shader *validShader = context->getShader(id);
1077
1078 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001079 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001080 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001081 {
Jamie Madille0472f32018-11-27 16:32:45 -05001082 context->validationError(GL_INVALID_OPERATION, kExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001083 }
1084 else
1085 {
Jamie Madille0472f32018-11-27 16:32:45 -05001086 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001087 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001088 }
Dian Xiang769769a2015-09-09 15:20:08 -07001089
1090 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001091}
1092
Jamie Madill43da7c42018-08-01 11:34:49 -04001093bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001094{
Geoff Langfa125c92017-10-24 13:01:46 -04001095 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001096 {
Geoff Langfa125c92017-10-24 13:01:46 -04001097 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1098 {
Jamie Madille0472f32018-11-27 16:32:45 -05001099 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langfa125c92017-10-24 13:01:46 -04001100 return false;
1101 }
Jamie Madillb4472272014-07-03 10:38:55 -04001102
Geoff Langfa125c92017-10-24 13:01:46 -04001103 // Color attachment 0 is validated below because it is always valid
1104 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001105 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001106 {
Jamie Madille0472f32018-11-27 16:32:45 -05001107 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001108 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001109 }
1110 }
1111 else
1112 {
1113 switch (attachment)
1114 {
Geoff Langfa125c92017-10-24 13:01:46 -04001115 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001116 case GL_DEPTH_ATTACHMENT:
1117 case GL_STENCIL_ATTACHMENT:
1118 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001119
He Yunchaoced53ae2016-11-29 15:00:51 +08001120 case GL_DEPTH_STENCIL_ATTACHMENT:
1121 if (!context->getExtensions().webglCompatibility &&
1122 context->getClientMajorVersion() < 3)
1123 {
Jamie Madille0472f32018-11-27 16:32:45 -05001124 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001125 return false;
1126 }
1127 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001128
He Yunchaoced53ae2016-11-29 15:00:51 +08001129 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001130 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001131 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001132 }
1133 }
1134
1135 return true;
1136}
1137
Jamie Madill5b772312018-03-08 20:28:32 -05001138bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001139 GLenum target,
1140 GLsizei samples,
1141 GLenum internalformat,
1142 GLsizei width,
1143 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001144{
1145 switch (target)
1146 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001147 case GL_RENDERBUFFER:
1148 break;
1149 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001150 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001151 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001152 }
1153
1154 if (width < 0 || height < 0 || samples < 0)
1155 {
Jamie Madille0472f32018-11-27 16:32:45 -05001156 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001157 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001158 }
1159
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001160 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1161 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1162
1163 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001164 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 {
Jamie Madille0472f32018-11-27 16:32:45 -05001166 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001167 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001168 }
1169
1170 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1171 // 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 -08001172 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001173 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001174 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 {
Jamie Madille0472f32018-11-27 16:32:45 -05001176 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001177 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001178 }
1179
Geoff Langaae65a42014-05-26 12:43:44 -04001180 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 {
Jamie Madille0472f32018-11-27 16:32:45 -05001182 context->validationError(GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04001183 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 }
1185
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001186 GLuint handle = context->getGLState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001187 if (handle == 0)
1188 {
Jamie Madille0472f32018-11-27 16:32:45 -05001189 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001190 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001191 }
1192
1193 return true;
1194}
1195
Jamie Madill43da7c42018-08-01 11:34:49 -04001196bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001197 GLenum target,
1198 GLenum attachment,
1199 GLenum renderbuffertarget,
1200 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001201{
Geoff Lange8afa902017-09-27 15:00:43 -04001202 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001203 {
Jamie Madille0472f32018-11-27 16:32:45 -05001204 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001205 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001206 }
1207
Jamie Madill43da7c42018-08-01 11:34:49 -04001208 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209
Jamie Madill84115c92015-04-23 15:00:07 -04001210 ASSERT(framebuffer);
1211 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001212 {
Jamie Madille0472f32018-11-27 16:32:45 -05001213 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001214 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001215 }
1216
Jamie Madillb4472272014-07-03 10:38:55 -04001217 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001218 {
Jamie Madillb4472272014-07-03 10:38:55 -04001219 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001220 }
1221
Jamie Madillab9d82c2014-01-21 16:38:14 -05001222 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1223 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1224 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1225 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1226 if (renderbuffer != 0)
1227 {
1228 if (!context->getRenderbuffer(renderbuffer))
1229 {
Jamie Madille0472f32018-11-27 16:32:45 -05001230 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001231 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001232 }
1233 }
1234
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001235 return true;
1236}
1237
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001238bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001239 GLint srcX0,
1240 GLint srcY0,
1241 GLint srcX1,
1242 GLint srcY1,
1243 GLint dstX0,
1244 GLint dstY0,
1245 GLint dstX1,
1246 GLint dstY1,
1247 GLbitfield mask,
1248 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001249{
1250 switch (filter)
1251 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001252 case GL_NEAREST:
1253 break;
1254 case GL_LINEAR:
1255 break;
1256 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001257 context->validationError(GL_INVALID_ENUM, kBlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001258 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001259 }
1260
1261 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1262 {
Jamie Madille0472f32018-11-27 16:32:45 -05001263 context->validationError(GL_INVALID_VALUE, kBlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001264 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001265 }
1266
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001267 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1268 // color buffer, leaving only nearest being unfiltered from above
1269 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1270 {
Jamie Madille0472f32018-11-27 16:32:45 -05001271 context->validationError(GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001272 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001273 }
1274
Jamie Madill7f232932018-09-12 11:03:06 -04001275 const auto &glState = context->getGLState();
1276 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1277 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001278
1279 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001280 {
Jamie Madille0472f32018-11-27 16:32:45 -05001281 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001282 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001283 }
1284
Jamie Madill427064d2018-04-13 16:20:34 -04001285 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001286 {
Jamie Madill48faf802014-11-06 15:27:22 -05001287 return false;
1288 }
1289
Jamie Madill427064d2018-04-13 16:20:34 -04001290 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001291 {
Jamie Madill48faf802014-11-06 15:27:22 -05001292 return false;
1293 }
1294
Qin Jiajiaaef92162018-02-27 13:51:44 +08001295 if (readFramebuffer->id() == drawFramebuffer->id())
1296 {
Jamie Madille0472f32018-11-27 16:32:45 -05001297 context->validationError(GL_INVALID_OPERATION, kBlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001298 return false;
1299 }
1300
Jamie Madille98b1b52018-03-08 09:47:23 -05001301 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001302 {
Geoff Langb1196682014-07-23 13:47:29 -04001303 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001304 }
1305
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001306 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1307 // always run it in order to avoid triggering driver bugs.
1308 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1309 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001310 {
Jamie Madille0472f32018-11-27 16:32:45 -05001311 context->validationError(GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001312 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001313 }
1314
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001315 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1316
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001317 if (mask & GL_COLOR_BUFFER_BIT)
1318 {
Jamie Madill7f232932018-09-12 11:03:06 -04001319 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1320 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001321
He Yunchao66a41a22016-12-15 16:45:05 +08001322 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001323 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001324 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001325
Geoff Langa15472a2015-08-11 11:48:03 -04001326 for (size_t drawbufferIdx = 0;
1327 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001328 {
Geoff Langa15472a2015-08-11 11:48:03 -04001329 const FramebufferAttachment *attachment =
1330 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1331 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001332 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001333 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001334
Geoff Langb2f3d052013-08-13 12:49:27 -04001335 // The GL ES 3.0.2 spec (pg 193) states that:
1336 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001337 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1338 // as well
1339 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1340 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001341 // Changes with EXT_color_buffer_float:
1342 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001343 GLenum readComponentType = readFormat.info->componentType;
1344 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001345 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001346 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001347 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001348 drawComponentType == GL_SIGNED_NORMALIZED);
1349
1350 if (extensions.colorBufferFloat)
1351 {
1352 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1353 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1354
1355 if (readFixedOrFloat != drawFixedOrFloat)
1356 {
Jamie Madill610640f2018-11-21 17:28:41 -05001357 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001358 kBlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001359 return false;
1360 }
1361 }
1362 else if (readFixedPoint != drawFixedPoint)
1363 {
Jamie Madille0472f32018-11-27 16:32:45 -05001364 context->validationError(GL_INVALID_OPERATION, kBlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001365 return false;
1366 }
1367
1368 if (readComponentType == GL_UNSIGNED_INT &&
1369 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001370 {
Jamie Madill610640f2018-11-21 17:28:41 -05001371 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001372 kBlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001373 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 }
1375
Jamie Madill6163c752015-12-07 16:32:59 -05001376 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001377 {
Jamie Madill610640f2018-11-21 17:28:41 -05001378 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001379 kBlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001380 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001381 }
1382
Jamie Madilla3944d42016-07-22 22:13:26 -04001383 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001384 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001385 {
Jamie Madill610640f2018-11-21 17:28:41 -05001386 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001387 kBlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001388 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001389 }
Geoff Lange4915782017-04-12 15:19:07 -04001390
1391 if (context->getExtensions().webglCompatibility &&
1392 *readColorBuffer == *attachment)
1393 {
Jamie Madille0472f32018-11-27 16:32:45 -05001394 context->validationError(GL_INVALID_OPERATION, kBlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001395 return false;
1396 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001397 }
1398 }
1399
Jamie Madilla3944d42016-07-22 22:13:26 -04001400 if ((readFormat.info->componentType == GL_INT ||
1401 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1402 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001403 {
Jamie Madille0472f32018-11-27 16:32:45 -05001404 context->validationError(GL_INVALID_OPERATION, kBlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001405 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001406 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001407 }
He Yunchao66a41a22016-12-15 16:45:05 +08001408 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1409 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1410 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1411 // situation is an application error that would lead to a crash in ANGLE.
1412 else if (drawFramebuffer->hasEnabledDrawBuffer())
1413 {
Jamie Madille0472f32018-11-27 16:32:45 -05001414 context->validationError(GL_INVALID_OPERATION, kBlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001415 return false;
1416 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001417 }
1418
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001420 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1421 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001423 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001424 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001425 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001426 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001427 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001428 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001429
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001430 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001431 {
Kenneth Russell69382852017-07-21 16:38:44 -04001432 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001433 {
Jamie Madill610640f2018-11-21 17:28:41 -05001434 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001435 kBlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001436 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001437 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001438
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001439 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001440 {
Jamie Madille0472f32018-11-27 16:32:45 -05001441 context->validationError(GL_INVALID_OPERATION, kBlitMultisampledBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001442 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001443 }
Geoff Lange4915782017-04-12 15:19:07 -04001444
1445 if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer)
1446 {
Jamie Madille0472f32018-11-27 16:32:45 -05001447 context->validationError(GL_INVALID_OPERATION, kBlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001448 return false;
1449 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001450 }
He Yunchao66a41a22016-12-15 16:45:05 +08001451 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1452 else if (drawBuffer)
1453 {
Jamie Madille0472f32018-11-27 16:32:45 -05001454 context->validationError(GL_INVALID_OPERATION, kBlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001455 return false;
1456 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001457 }
1458 }
1459
Martin Radeva3ed4572017-07-27 18:29:37 +03001460 // ANGLE_multiview, Revision 1:
1461 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001462 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1463 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1464 // views in the current read framebuffer is more than one.
1465 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001466 {
Jamie Madille0472f32018-11-27 16:32:45 -05001467 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001468 return false;
1469 }
1470 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1471 {
Jamie Madille0472f32018-11-27 16:32:45 -05001472 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001473 return false;
1474 }
1475
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001476 return true;
1477}
1478
Jamie Madill4928b7c2017-06-20 12:57:39 -04001479bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001480 GLint x,
1481 GLint y,
1482 GLsizei width,
1483 GLsizei height,
1484 GLenum format,
1485 GLenum type,
1486 GLsizei bufSize,
1487 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001488 GLsizei *columns,
1489 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001490 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001491{
1492 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001493 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001494 return false;
1495 }
1496
Brandon Jonesd1049182018-03-28 10:02:20 -07001497 GLsizei writeLength = 0;
1498 GLsizei writeColumns = 0;
1499 GLsizei writeRows = 0;
1500
1501 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1502 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001503 {
Geoff Langb1196682014-07-23 13:47:29 -04001504 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001505 }
1506
Brandon Jonesd1049182018-03-28 10:02:20 -07001507 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001508 {
Geoff Langb1196682014-07-23 13:47:29 -04001509 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001510 }
1511
Brandon Jonesd1049182018-03-28 10:02:20 -07001512 SetRobustLengthParam(length, writeLength);
1513 SetRobustLengthParam(columns, writeColumns);
1514 SetRobustLengthParam(rows, writeRows);
1515
Jamie Madillc29968b2016-01-20 11:17:23 -05001516 return true;
1517}
1518
1519bool ValidateReadnPixelsEXT(Context *context,
1520 GLint x,
1521 GLint y,
1522 GLsizei width,
1523 GLsizei height,
1524 GLenum format,
1525 GLenum type,
1526 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001527 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001528{
1529 if (bufSize < 0)
1530 {
Jamie Madille0472f32018-11-27 16:32:45 -05001531 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001532 return false;
1533 }
1534
Geoff Lang62fce5b2016-09-30 10:46:35 -04001535 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001536 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001537}
Jamie Madill26e91952014-03-05 15:01:27 -05001538
Jamie Madill4928b7c2017-06-20 12:57:39 -04001539bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001540 GLint x,
1541 GLint y,
1542 GLsizei width,
1543 GLsizei height,
1544 GLenum format,
1545 GLenum type,
1546 GLsizei bufSize,
1547 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001548 GLsizei *columns,
1549 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001550 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001551{
Brandon Jonesd1049182018-03-28 10:02:20 -07001552 GLsizei writeLength = 0;
1553 GLsizei writeColumns = 0;
1554 GLsizei writeRows = 0;
1555
Geoff Lang62fce5b2016-09-30 10:46:35 -04001556 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001557 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001558 return false;
1559 }
1560
Brandon Jonesd1049182018-03-28 10:02:20 -07001561 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1562 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001563 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001564 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001565 }
1566
Brandon Jonesd1049182018-03-28 10:02:20 -07001567 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001568 {
1569 return false;
1570 }
1571
Brandon Jonesd1049182018-03-28 10:02:20 -07001572 SetRobustLengthParam(length, writeLength);
1573 SetRobustLengthParam(columns, writeColumns);
1574 SetRobustLengthParam(rows, writeRows);
1575
Geoff Lang62fce5b2016-09-30 10:46:35 -04001576 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001577}
1578
Jamie Madill43da7c42018-08-01 11:34:49 -04001579bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001580{
1581 if (!context->getExtensions().occlusionQueryBoolean &&
1582 !context->getExtensions().disjointTimerQuery)
1583 {
Jamie Madille0472f32018-11-27 16:32:45 -05001584 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001585 return false;
1586 }
1587
Olli Etuaho41997e72016-03-10 13:38:39 +02001588 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001589}
1590
Jamie Madill43da7c42018-08-01 11:34:49 -04001591bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001592{
1593 if (!context->getExtensions().occlusionQueryBoolean &&
1594 !context->getExtensions().disjointTimerQuery)
1595 {
Jamie Madille0472f32018-11-27 16:32:45 -05001596 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001597 return false;
1598 }
1599
Olli Etuaho41997e72016-03-10 13:38:39 +02001600 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001601}
1602
Jamie Madill43da7c42018-08-01 11:34:49 -04001603bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001604{
1605 if (!context->getExtensions().occlusionQueryBoolean &&
1606 !context->getExtensions().disjointTimerQuery)
1607 {
Jamie Madille0472f32018-11-27 16:32:45 -05001608 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Jamie Madillf0e04492017-08-26 15:28:42 -04001609 return false;
1610 }
1611
1612 return true;
1613}
1614
Jamie Madill43da7c42018-08-01 11:34:49 -04001615bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001616{
1617 if (!ValidQueryType(context, target))
1618 {
Jamie Madille0472f32018-11-27 16:32:45 -05001619 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001620 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001621 }
1622
1623 if (id == 0)
1624 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001625 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001626 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001627 }
1628
1629 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1630 // of zero, if the active query object name for <target> is non-zero (for the
1631 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1632 // the active query for either target is non-zero), if <id> is the name of an
1633 // existing query object whose type does not match <target>, or if <id> is the
1634 // active query object name for any query type, the error INVALID_OPERATION is
1635 // generated.
1636
1637 // Ensure no other queries are active
1638 // NOTE: If other queries than occlusion are supported, we will need to check
1639 // separately that:
1640 // a) The query ID passed is not the current active query for any target/type
1641 // b) There are no active queries for the requested target (and in the case
1642 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1643 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001644
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001645 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001646 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001647 context->validationError(GL_INVALID_OPERATION, kOtherQueryActive);
Geoff Langb1196682014-07-23 13:47:29 -04001648 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001649 }
1650
1651 Query *queryObject = context->getQuery(id, true, target);
1652
1653 // check that name was obtained with glGenQueries
1654 if (!queryObject)
1655 {
Jamie Madille0472f32018-11-27 16:32:45 -05001656 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001657 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001658 }
1659
1660 // check for type mismatch
1661 if (queryObject->getType() != target)
1662 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001663 context->validationError(GL_INVALID_OPERATION, kQueryTargetMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001664 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001665 }
1666
1667 return true;
1668}
1669
Jamie Madill43da7c42018-08-01 11:34:49 -04001670bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001671{
1672 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001673 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001674 {
Jamie Madille0472f32018-11-27 16:32:45 -05001675 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001676 return false;
1677 }
1678
1679 return ValidateBeginQueryBase(context, target, id);
1680}
1681
Jamie Madill43da7c42018-08-01 11:34:49 -04001682bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001683{
1684 if (!ValidQueryType(context, target))
1685 {
Jamie Madille0472f32018-11-27 16:32:45 -05001686 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001687 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001688 }
1689
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001690 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001691
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001692 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001693 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001694 context->validationError(GL_INVALID_OPERATION, kQueryInactive);
Geoff Langb1196682014-07-23 13:47:29 -04001695 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001696 }
1697
Jamie Madill45c785d2014-05-13 14:09:34 -04001698 return true;
1699}
1700
Jamie Madill43da7c42018-08-01 11:34:49 -04001701bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001702{
1703 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001704 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001705 {
Jamie Madille0472f32018-11-27 16:32:45 -05001706 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001707 return false;
1708 }
1709
1710 return ValidateEndQueryBase(context, target);
1711}
1712
Corentin Wallezad3ae902018-03-09 13:40:42 -05001713bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001714{
1715 if (!context->getExtensions().disjointTimerQuery)
1716 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001717 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001718 return false;
1719 }
1720
Corentin Wallezad3ae902018-03-09 13:40:42 -05001721 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001722 {
Jamie Madille0472f32018-11-27 16:32:45 -05001723 context->validationError(GL_INVALID_ENUM, kInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001724 return false;
1725 }
1726
1727 Query *queryObject = context->getQuery(id, true, target);
1728 if (queryObject == nullptr)
1729 {
Jamie Madille0472f32018-11-27 16:32:45 -05001730 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001731 return false;
1732 }
1733
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001734 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001735 {
Jamie Madille0472f32018-11-27 16:32:45 -05001736 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001737 return false;
1738 }
1739
1740 return true;
1741}
1742
Corentin Wallezad3ae902018-03-09 13:40:42 -05001743bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001744{
Geoff Lang2186c382016-10-14 10:54:54 -04001745 if (numParams)
1746 {
1747 *numParams = 0;
1748 }
1749
Corentin Wallezad3ae902018-03-09 13:40:42 -05001750 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001751 {
Jamie Madille0472f32018-11-27 16:32:45 -05001752 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001753 return false;
1754 }
1755
1756 switch (pname)
1757 {
1758 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001759 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001760 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001761 context->validationError(GL_INVALID_ENUM, kInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001762 return false;
1763 }
1764 break;
1765 case GL_QUERY_COUNTER_BITS_EXT:
1766 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001767 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001768 {
Jamie Madille0472f32018-11-27 16:32:45 -05001769 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001770 return false;
1771 }
1772 break;
1773 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001774 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001775 return false;
1776 }
1777
Geoff Lang2186c382016-10-14 10:54:54 -04001778 if (numParams)
1779 {
1780 // All queries return only one value
1781 *numParams = 1;
1782 }
1783
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001784 return true;
1785}
1786
Corentin Wallezad3ae902018-03-09 13:40:42 -05001787bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001788{
1789 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001790 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001791 {
Jamie Madille0472f32018-11-27 16:32:45 -05001792 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001793 return false;
1794 }
1795
Geoff Lang2186c382016-10-14 10:54:54 -04001796 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001797}
1798
Geoff Lang2186c382016-10-14 10:54:54 -04001799bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001800 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001801 GLenum pname,
1802 GLsizei bufSize,
1803 GLsizei *length,
1804 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001805{
Geoff Lang2186c382016-10-14 10:54:54 -04001806 if (!ValidateRobustEntryPoint(context, bufSize))
1807 {
1808 return false;
1809 }
1810
Brandon Jonesd1049182018-03-28 10:02:20 -07001811 GLsizei numParams = 0;
1812
1813 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001814 {
1815 return false;
1816 }
1817
Brandon Jonesd1049182018-03-28 10:02:20 -07001818 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001819 {
1820 return false;
1821 }
1822
Brandon Jonesd1049182018-03-28 10:02:20 -07001823 SetRobustLengthParam(length, numParams);
1824
Geoff Lang2186c382016-10-14 10:54:54 -04001825 return true;
1826}
1827
1828bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1829{
1830 if (numParams)
1831 {
1832 *numParams = 0;
1833 }
1834
Corentin Wallezad3ae902018-03-09 13:40:42 -05001835 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001836
1837 if (!queryObject)
1838 {
Jamie Madille0472f32018-11-27 16:32:45 -05001839 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001840 return false;
1841 }
1842
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001843 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001844 {
Jamie Madille0472f32018-11-27 16:32:45 -05001845 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001846 return false;
1847 }
1848
1849 switch (pname)
1850 {
1851 case GL_QUERY_RESULT_EXT:
1852 case GL_QUERY_RESULT_AVAILABLE_EXT:
1853 break;
1854
1855 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001856 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001857 return false;
1858 }
1859
Geoff Lang2186c382016-10-14 10:54:54 -04001860 if (numParams)
1861 {
1862 *numParams = 1;
1863 }
1864
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001865 return true;
1866}
1867
1868bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1869{
1870 if (!context->getExtensions().disjointTimerQuery)
1871 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001872 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001873 return false;
1874 }
Geoff Lang2186c382016-10-14 10:54:54 -04001875 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1876}
1877
1878bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1879 GLuint id,
1880 GLenum pname,
1881 GLsizei bufSize,
1882 GLsizei *length,
1883 GLint *params)
1884{
1885 if (!context->getExtensions().disjointTimerQuery)
1886 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001887 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001888 return false;
1889 }
1890
1891 if (!ValidateRobustEntryPoint(context, bufSize))
1892 {
1893 return false;
1894 }
1895
Brandon Jonesd1049182018-03-28 10:02:20 -07001896 GLsizei numParams = 0;
1897
1898 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001899 {
1900 return false;
1901 }
1902
Brandon Jonesd1049182018-03-28 10:02:20 -07001903 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001904 {
1905 return false;
1906 }
1907
Brandon Jonesd1049182018-03-28 10:02:20 -07001908 SetRobustLengthParam(length, numParams);
1909
Geoff Lang2186c382016-10-14 10:54:54 -04001910 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001911}
1912
1913bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1914{
1915 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001916 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001917 {
Jamie Madille0472f32018-11-27 16:32:45 -05001918 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001919 return false;
1920 }
Geoff Lang2186c382016-10-14 10:54:54 -04001921 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1922}
1923
1924bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1925 GLuint id,
1926 GLenum pname,
1927 GLsizei bufSize,
1928 GLsizei *length,
1929 GLuint *params)
1930{
1931 if (!context->getExtensions().disjointTimerQuery &&
1932 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1933 {
Jamie Madille0472f32018-11-27 16:32:45 -05001934 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001935 return false;
1936 }
1937
1938 if (!ValidateRobustEntryPoint(context, bufSize))
1939 {
1940 return false;
1941 }
1942
Brandon Jonesd1049182018-03-28 10:02:20 -07001943 GLsizei numParams = 0;
1944
1945 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001946 {
1947 return false;
1948 }
1949
Brandon Jonesd1049182018-03-28 10:02:20 -07001950 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001951 {
1952 return false;
1953 }
1954
Brandon Jonesd1049182018-03-28 10:02:20 -07001955 SetRobustLengthParam(length, numParams);
1956
Geoff Lang2186c382016-10-14 10:54:54 -04001957 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001958}
1959
1960bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1961{
1962 if (!context->getExtensions().disjointTimerQuery)
1963 {
Jamie Madille0472f32018-11-27 16:32:45 -05001964 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001965 return false;
1966 }
Geoff Lang2186c382016-10-14 10:54:54 -04001967 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1968}
1969
1970bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1971 GLuint id,
1972 GLenum pname,
1973 GLsizei bufSize,
1974 GLsizei *length,
1975 GLint64 *params)
1976{
1977 if (!context->getExtensions().disjointTimerQuery)
1978 {
Jamie Madille0472f32018-11-27 16:32:45 -05001979 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001980 return false;
1981 }
1982
1983 if (!ValidateRobustEntryPoint(context, bufSize))
1984 {
1985 return false;
1986 }
1987
Brandon Jonesd1049182018-03-28 10:02:20 -07001988 GLsizei numParams = 0;
1989
1990 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001991 {
1992 return false;
1993 }
1994
Brandon Jonesd1049182018-03-28 10:02:20 -07001995 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001996 {
1997 return false;
1998 }
1999
Brandon Jonesd1049182018-03-28 10:02:20 -07002000 SetRobustLengthParam(length, numParams);
2001
Geoff Lang2186c382016-10-14 10:54:54 -04002002 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002003}
2004
2005bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
2006{
2007 if (!context->getExtensions().disjointTimerQuery)
2008 {
Jamie Madille0472f32018-11-27 16:32:45 -05002009 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002010 return false;
2011 }
Geoff Lang2186c382016-10-14 10:54:54 -04002012 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
2013}
2014
2015bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
2016 GLuint id,
2017 GLenum pname,
2018 GLsizei bufSize,
2019 GLsizei *length,
2020 GLuint64 *params)
2021{
2022 if (!context->getExtensions().disjointTimerQuery)
2023 {
Jamie Madille0472f32018-11-27 16:32:45 -05002024 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002025 return false;
2026 }
2027
2028 if (!ValidateRobustEntryPoint(context, bufSize))
2029 {
2030 return false;
2031 }
2032
Brandon Jonesd1049182018-03-28 10:02:20 -07002033 GLsizei numParams = 0;
2034
2035 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002036 {
2037 return false;
2038 }
2039
Brandon Jonesd1049182018-03-28 10:02:20 -07002040 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002041 {
2042 return false;
2043 }
2044
Brandon Jonesd1049182018-03-28 10:02:20 -07002045 SetRobustLengthParam(length, numParams);
2046
Geoff Lang2186c382016-10-14 10:54:54 -04002047 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002048}
2049
Jamie Madill5b772312018-03-08 20:28:32 -05002050bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002051 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002052 GLint location,
2053 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002054 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002055{
Jiajia Qin5451d532017-11-16 17:16:34 +08002056 // TODO(Jiajia): Add image uniform check in future.
2057 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002058 {
Jamie Madille0472f32018-11-27 16:32:45 -05002059 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002060 return false;
2061 }
2062
Jiajia Qin5451d532017-11-16 17:16:34 +08002063 if (!program)
2064 {
Jamie Madille0472f32018-11-27 16:32:45 -05002065 context->validationError(GL_INVALID_OPERATION, kInvalidProgramName);
Jiajia Qin5451d532017-11-16 17:16:34 +08002066 return false;
2067 }
2068
2069 if (!program->isLinked())
2070 {
Jamie Madille0472f32018-11-27 16:32:45 -05002071 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiajia Qin5451d532017-11-16 17:16:34 +08002072 return false;
2073 }
2074
2075 if (location == -1)
2076 {
2077 // Silently ignore the uniform command
2078 return false;
2079 }
2080
2081 const auto &uniformLocations = program->getUniformLocations();
2082 size_t castedLocation = static_cast<size_t>(location);
2083 if (castedLocation >= uniformLocations.size())
2084 {
Jamie Madille0472f32018-11-27 16:32:45 -05002085 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002086 return false;
2087 }
2088
2089 const auto &uniformLocation = uniformLocations[castedLocation];
2090 if (uniformLocation.ignored)
2091 {
2092 // Silently ignore the uniform command
2093 return false;
2094 }
2095
2096 if (!uniformLocation.used())
2097 {
Jamie Madille0472f32018-11-27 16:32:45 -05002098 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002099 return false;
2100 }
2101
2102 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2103
2104 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002105 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002106 {
Jamie Madille0472f32018-11-27 16:32:45 -05002107 context->validationError(GL_INVALID_OPERATION, kInvalidUniformCount);
Jiajia Qin5451d532017-11-16 17:16:34 +08002108 return false;
2109 }
2110
2111 *uniformOut = &uniform;
2112 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002113}
2114
Jamie Madill5b772312018-03-08 20:28:32 -05002115bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002116 GLenum uniformType,
2117 GLsizei count,
2118 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002119{
Jiajia Qin5451d532017-11-16 17:16:34 +08002120 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2121 // It is compatible with INT or BOOL.
2122 // Do these cheap tests first, for a little extra speed.
2123 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002124 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002125 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002126 }
2127
Jiajia Qin5451d532017-11-16 17:16:34 +08002128 if (IsSamplerType(uniformType))
2129 {
2130 // Check that the values are in range.
2131 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2132 for (GLsizei i = 0; i < count; ++i)
2133 {
2134 if (value[i] < 0 || value[i] >= max)
2135 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002136 context->validationError(GL_INVALID_VALUE, kSamplerUniformValueOutOfRange);
Jiajia Qin5451d532017-11-16 17:16:34 +08002137 return false;
2138 }
2139 }
2140 return true;
2141 }
2142
Jamie Madillc3e37312018-11-30 15:25:39 -05002143 context->validationError(GL_INVALID_OPERATION, kUniformTypeMismatch);
Jiajia Qin5451d532017-11-16 17:16:34 +08002144 return false;
2145}
2146
Jamie Madill5b772312018-03-08 20:28:32 -05002147bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002148{
2149 // Check that the value type is compatible with uniform type.
2150 if (valueType == uniformType)
2151 {
2152 return true;
2153 }
2154
Jamie Madillc3e37312018-11-30 15:25:39 -05002155 context->validationError(GL_INVALID_OPERATION, kUniformTypeMismatch);
Jiajia Qin5451d532017-11-16 17:16:34 +08002156 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002157}
2158
Jamie Madill5b772312018-03-08 20:28:32 -05002159bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002160{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002161 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002162 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002163 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2164 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002165}
2166
Jamie Madill5b772312018-03-08 20:28:32 -05002167bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002168{
2169 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002170 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002171 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2172 ValidateUniform1ivValue(context, uniform->type, count, value);
2173}
2174
Jamie Madill5b772312018-03-08 20:28:32 -05002175bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002176 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002177 GLint location,
2178 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002179 GLboolean transpose)
2180{
Geoff Lang92019432017-11-20 13:09:34 -05002181 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002182 {
Jamie Madille0472f32018-11-27 16:32:45 -05002183 context->validationError(GL_INVALID_VALUE, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04002184 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002185 }
2186
Jamie Madill62d31cb2015-09-11 13:25:51 -04002187 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002188 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002189 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2190 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002191}
2192
Jamie Madill5b772312018-03-08 20:28:32 -05002193bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002194{
2195 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2196 {
Jamie Madille0472f32018-11-27 16:32:45 -05002197 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langb1196682014-07-23 13:47:29 -04002198 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002199 }
2200
Jamie Madill0af26e12015-03-05 19:54:33 -05002201 const Caps &caps = context->getCaps();
2202
Jamie Madill893ab082014-05-16 16:56:10 -04002203 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2204 {
2205 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2206
Jamie Madill0af26e12015-03-05 19:54:33 -05002207 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002208 {
Jamie Madille0472f32018-11-27 16:32:45 -05002209 context->validationError(GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
Geoff Langb1196682014-07-23 13:47:29 -04002210 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002211 }
2212 }
2213
2214 switch (pname)
2215 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002216 case GL_TEXTURE_BINDING_2D:
2217 case GL_TEXTURE_BINDING_CUBE_MAP:
2218 case GL_TEXTURE_BINDING_3D:
2219 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002220 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002221 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002222 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002223 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002224 {
Jamie Madille0472f32018-11-27 16:32:45 -05002225 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03002226 return false;
2227 }
2228 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002229 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2230 if (!context->getExtensions().textureRectangle)
2231 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002232 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002233 return false;
2234 }
2235 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002236 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2237 if (!context->getExtensions().eglStreamConsumerExternal &&
2238 !context->getExtensions().eglImageExternal)
2239 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002240 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002241 return false;
2242 }
2243 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002244
He Yunchaoced53ae2016-11-29 15:00:51 +08002245 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2246 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002247 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002248 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2249 ASSERT(readFramebuffer);
2250
Jamie Madill610640f2018-11-21 17:28:41 -05002251 if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002252 {
Geoff Langb1196682014-07-23 13:47:29 -04002253 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002254 }
2255
Jamie Madille98b1b52018-03-08 09:47:23 -05002256 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002257 {
Jamie Madille0472f32018-11-27 16:32:45 -05002258 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002259 return false;
2260 }
2261
Jamie Madille98b1b52018-03-08 09:47:23 -05002262 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002263 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002264 {
Jamie Madille0472f32018-11-27 16:32:45 -05002265 context->validationError(GL_INVALID_OPERATION, kReadBufferNotAttached);
Geoff Langb1196682014-07-23 13:47:29 -04002266 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002267 }
2268 }
2269 break;
2270
He Yunchaoced53ae2016-11-29 15:00:51 +08002271 default:
2272 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002273 }
2274
2275 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002276 if (*numParams == 0)
2277 {
2278 return false;
2279 }
2280
2281 return true;
2282}
2283
Brandon Jonesd1049182018-03-28 10:02:20 -07002284bool ValidateGetBooleanvRobustANGLE(Context *context,
2285 GLenum pname,
2286 GLsizei bufSize,
2287 GLsizei *length,
2288 GLboolean *params)
2289{
2290 GLenum nativeType;
2291 unsigned int numParams = 0;
2292
2293 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2294 {
2295 return false;
2296 }
2297
2298 SetRobustLengthParam(length, numParams);
2299
2300 return true;
2301}
2302
2303bool ValidateGetFloatvRobustANGLE(Context *context,
2304 GLenum pname,
2305 GLsizei bufSize,
2306 GLsizei *length,
2307 GLfloat *params)
2308{
2309 GLenum nativeType;
2310 unsigned int numParams = 0;
2311
2312 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2313 {
2314 return false;
2315 }
2316
2317 SetRobustLengthParam(length, numParams);
2318
2319 return true;
2320}
2321
2322bool ValidateGetIntegervRobustANGLE(Context *context,
2323 GLenum pname,
2324 GLsizei bufSize,
2325 GLsizei *length,
2326 GLint *data)
2327{
2328 GLenum nativeType;
2329 unsigned int numParams = 0;
2330
2331 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2332 {
2333 return false;
2334 }
2335
2336 SetRobustLengthParam(length, numParams);
2337
2338 return true;
2339}
2340
2341bool ValidateGetInteger64vRobustANGLE(Context *context,
2342 GLenum pname,
2343 GLsizei bufSize,
2344 GLsizei *length,
2345 GLint64 *data)
2346{
2347 GLenum nativeType;
2348 unsigned int numParams = 0;
2349
2350 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2351 {
2352 return false;
2353 }
2354
2355 if (nativeType == GL_INT_64_ANGLEX)
2356 {
2357 CastStateValues(context, nativeType, pname, numParams, data);
2358 return false;
2359 }
2360
2361 SetRobustLengthParam(length, numParams);
2362 return true;
2363}
2364
Jamie Madill5b772312018-03-08 20:28:32 -05002365bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002366 GLenum pname,
2367 GLsizei bufSize,
2368 GLenum *nativeType,
2369 unsigned int *numParams)
2370{
2371 if (!ValidateRobustEntryPoint(context, bufSize))
2372 {
2373 return false;
2374 }
2375
2376 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2377 {
2378 return false;
2379 }
2380
2381 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002382 {
2383 return false;
2384 }
2385
2386 return true;
2387}
2388
Jamie Madill5b772312018-03-08 20:28:32 -05002389bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002390 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002391 GLint level,
2392 GLenum internalformat,
2393 bool isSubImage,
2394 GLint xoffset,
2395 GLint yoffset,
2396 GLint zoffset,
2397 GLint x,
2398 GLint y,
2399 GLsizei width,
2400 GLsizei height,
2401 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002402 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002403{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002404 TextureType texType = TextureTargetToType(target);
2405
Brandon Jones6cad5662017-06-14 13:25:13 -07002406 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002407 {
Jamie Madille0472f32018-11-27 16:32:45 -05002408 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07002409 return false;
2410 }
2411
2412 if (width < 0 || height < 0)
2413 {
Jamie Madille0472f32018-11-27 16:32:45 -05002414 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002415 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002416 }
2417
He Yunchaoced53ae2016-11-29 15:00:51 +08002418 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2419 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002420 {
Jamie Madille0472f32018-11-27 16:32:45 -05002421 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002422 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002423 }
2424
2425 if (border != 0)
2426 {
Jamie Madille0472f32018-11-27 16:32:45 -05002427 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002428 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002429 }
2430
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002431 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002432 {
Jamie Madille0472f32018-11-27 16:32:45 -05002433 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002434 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002435 }
2436
Jamie Madill43da7c42018-08-01 11:34:49 -04002437 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002438 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002439 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002440 {
Geoff Langb1196682014-07-23 13:47:29 -04002441 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002442 }
2443
Jamie Madille98b1b52018-03-08 09:47:23 -05002444 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002445 {
Geoff Langb1196682014-07-23 13:47:29 -04002446 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002447 }
2448
Martin Radev138064f2016-07-15 12:03:41 +03002449 if (readFramebuffer->getReadBufferState() == GL_NONE)
2450 {
Jamie Madille0472f32018-11-27 16:32:45 -05002451 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002452 return false;
2453 }
2454
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002455 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2456 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002457 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002458 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002459 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2460 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002461 {
Jamie Madille0472f32018-11-27 16:32:45 -05002462 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002463 return false;
2464 }
2465
Martin Radev04e2c3b2017-07-27 16:54:35 +03002466 // ANGLE_multiview spec, Revision 1:
2467 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2468 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002469 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2470 // framebuffer is more than one.
2471 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002472 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002473 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
Martin Radev04e2c3b2017-07-27 16:54:35 +03002474 return false;
2475 }
2476
Jamie Madill43da7c42018-08-01 11:34:49 -04002477 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002478
Geoff Langaae65a42014-05-26 12:43:44 -04002479 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002480 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002481 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002482 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002483 maxDimension = caps.max2DTextureSize;
2484 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002485
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002486 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002487 maxDimension = caps.maxCubeMapTextureSize;
2488 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002489
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002490 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002491 maxDimension = caps.maxRectangleTextureSize;
2492 break;
2493
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002494 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002495 maxDimension = caps.max2DTextureSize;
2496 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002497
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002498 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002499 maxDimension = caps.max3DTextureSize;
2500 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002501
He Yunchaoced53ae2016-11-29 15:00:51 +08002502 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002503 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002504 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002505 }
2506
Jamie Madill43da7c42018-08-01 11:34:49 -04002507 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002508 if (!texture)
2509 {
Jamie Madille0472f32018-11-27 16:32:45 -05002510 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002511 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002512 }
2513
Geoff Lang69cce582015-09-17 13:20:36 -04002514 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002515 {
Jamie Madille0472f32018-11-27 16:32:45 -05002516 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002517 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002518 }
2519
Jamie Madill43da7c42018-08-01 11:34:49 -04002520 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002521 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002522 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002523
Geoff Lang966c9402017-04-18 12:38:27 -04002524 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002525 {
Jamie Madille0472f32018-11-27 16:32:45 -05002526 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Langa9be0dc2014-12-17 12:34:40 -05002527 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002528 }
2529
2530 if (isSubImage)
2531 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002532 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2533 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2534 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002535 {
Jamie Madille0472f32018-11-27 16:32:45 -05002536 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002537 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002538 }
2539 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002540 else
2541 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002542 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002543 {
Jamie Madille0472f32018-11-27 16:32:45 -05002544 context->validationError(GL_INVALID_VALUE, kCubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002545 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002546 }
2547
Geoff Langeb66a6e2016-10-31 13:06:12 -04002548 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002549 {
Jamie Madille0472f32018-11-27 16:32:45 -05002550 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002551 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002552 }
2553
2554 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002555 if (static_cast<int>(width) > maxLevelDimension ||
2556 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002557 {
Jamie Madille0472f32018-11-27 16:32:45 -05002558 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002559 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002560 }
2561 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002562
Jamie Madill0c8abca2016-07-22 20:21:26 -04002563 if (textureFormatOut)
2564 {
2565 *textureFormatOut = texture->getFormat(target, level);
2566 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002567
2568 // Detect texture copying feedback loops for WebGL.
2569 if (context->getExtensions().webglCompatibility)
2570 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002571 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002572 {
Jamie Madille0472f32018-11-27 16:32:45 -05002573 context->validationError(GL_INVALID_OPERATION, kFeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002574 return false;
2575 }
2576 }
2577
Jamie Madill560a8d82014-05-21 13:06:20 -04002578 return true;
2579}
2580
Jamie Madillb42162f2018-08-20 12:58:37 -04002581// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2582// completeness check.
2583const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002584{
2585 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002586 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002587
2588 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2589 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2590 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002591 VertexArray *vertexArray = state.getVertexArray();
2592 ASSERT(vertexArray);
2593
2594 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002595 {
Jamie Madille0472f32018-11-27 16:32:45 -05002596 return kBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002597 }
2598
2599 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2600 // Section 6.10 of the WebGL 1.0 spec.
2601 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002602 ASSERT(framebuffer);
2603
Jamie Madille7d80f32018-08-08 15:49:23 -04002604 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2605 {
2606 ASSERT(framebuffer);
2607 const FramebufferAttachment *dsAttachment =
2608 framebuffer->getStencilOrDepthStencilAttachment();
2609 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2610 ASSERT(stencilBits <= 8);
2611
2612 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2613 if (depthStencilState.stencilTest && stencilBits > 0)
2614 {
2615 GLuint maxStencilValue = (1 << stencilBits) - 1;
2616
2617 bool differentRefs =
2618 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2619 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2620 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2621 (depthStencilState.stencilBackWritemask & maxStencilValue);
2622 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2623 (depthStencilState.stencilBackMask & maxStencilValue);
2624
2625 if (differentRefs || differentWritemasks || differentMasks)
2626 {
2627 if (!extensions.webglCompatibility)
2628 {
2629 WARN() << "This ANGLE implementation does not support separate front/back "
2630 "stencil writemasks, reference values, or stencil mask values.";
2631 }
Jamie Madille0472f32018-11-27 16:32:45 -05002632 return kStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002633 }
2634 }
2635 }
2636
2637 if (!framebuffer->isComplete(context))
2638 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002639 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
Jamie Madille0472f32018-11-27 16:32:45 -05002640 return kDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002641 }
2642
2643 if (context->getStateCache().hasAnyEnabledClientAttrib())
2644 {
2645 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2646 {
2647 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2648 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2649 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2650 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madille0472f32018-11-27 16:32:45 -05002651 return kVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002652 }
2653
2654 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2655 {
2656 // This is an application error that would normally result in a crash, but we catch it
2657 // and return an error
Jamie Madille0472f32018-11-27 16:32:45 -05002658 return kVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002659 }
2660 }
2661
2662 // If we are running GLES1, there is no current program.
2663 if (context->getClientVersion() >= Version(2, 0))
2664 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002665 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002666 if (!program)
2667 {
Jamie Madille0472f32018-11-27 16:32:45 -05002668 return kProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002669 }
2670
2671 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2672 // vertex shader stage or fragment shader stage is a undefined behaviour.
2673 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2674 // produce undefined result.
2675 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2676 !program->hasLinkedShaderStage(ShaderType::Fragment))
2677 {
Jamie Madille0472f32018-11-27 16:32:45 -05002678 return kNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002679 }
2680
2681 if (!program->validateSamplers(nullptr, context->getCaps()))
2682 {
Jamie Madille0472f32018-11-27 16:32:45 -05002683 return kTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002684 }
2685
2686 if (extensions.multiview)
2687 {
2688 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2689 const int framebufferNumViews = framebuffer->getNumViews();
2690 if (framebufferNumViews != programNumViews)
2691 {
Jamie Madille0472f32018-11-27 16:32:45 -05002692 return kMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002693 }
2694
2695 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2696 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
Jamie Madill3a256222018-12-08 09:56:39 -05002697 !transformFeedbackObject->isPaused() && framebufferNumViews > 1)
Jamie Madille7d80f32018-08-08 15:49:23 -04002698 {
Jamie Madille0472f32018-11-27 16:32:45 -05002699 return kMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002700 }
2701
2702 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2703 state.isQueryActive(QueryType::TimeElapsed))
2704 {
Jamie Madille0472f32018-11-27 16:32:45 -05002705 return kMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002706 }
2707 }
2708
2709 // Uniform buffer validation
2710 for (unsigned int uniformBlockIndex = 0;
2711 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2712 {
2713 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002714 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002715 const OffsetBindingPointer<Buffer> &uniformBuffer =
2716 state.getIndexedUniformBuffer(blockBinding);
2717
2718 if (uniformBuffer.get() == nullptr)
2719 {
2720 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002721 return kUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002722 }
2723
2724 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2725 if (uniformBufferSize < uniformBlock.dataSize)
2726 {
2727 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002728 return kUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002729 }
2730
2731 if (extensions.webglCompatibility &&
2732 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2733 {
Jamie Madille0472f32018-11-27 16:32:45 -05002734 return kUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002735 }
2736 }
2737
2738 // Do some additonal WebGL-specific validation
2739 if (extensions.webglCompatibility)
2740 {
2741 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2742 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2743 transformFeedbackObject->buffersBoundForOtherUse())
2744 {
Jamie Madille0472f32018-11-27 16:32:45 -05002745 return kTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002746 }
2747
2748 // Detect rendering feedback loops for WebGL.
2749 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2750 {
Jamie Madille0472f32018-11-27 16:32:45 -05002751 return kFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002752 }
2753
2754 // Detect that the vertex shader input types match the attribute types
2755 if (!ValidateVertexShaderAttributeTypeMatch(context))
2756 {
Jamie Madille0472f32018-11-27 16:32:45 -05002757 return kVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002758 }
2759
2760 // Detect that the color buffer types match the fragment shader output types
2761 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2762 {
Jamie Madille0472f32018-11-27 16:32:45 -05002763 return kDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002764 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002765
2766 const VertexArray *vao = context->getGLState().getVertexArray();
2767 if (vao->hasTransformFeedbackBindingConflict(context))
2768 {
Jamie Madille0472f32018-11-27 16:32:45 -05002769 return kVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002770 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002771 }
2772 }
2773
Jamie Madillb42162f2018-08-20 12:58:37 -04002774 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002775}
2776
Jamie Madill16e28fd2018-09-12 11:03:05 -04002777bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002778{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002779 const Extensions &extensions = context->getExtensions();
2780
Jamie Madill1aeb1312014-06-20 13:21:25 -04002781 switch (mode)
2782 {
Jamie Madill493f9572018-05-24 19:52:15 -04002783 case PrimitiveMode::Points:
2784 case PrimitiveMode::Lines:
2785 case PrimitiveMode::LineLoop:
2786 case PrimitiveMode::LineStrip:
2787 case PrimitiveMode::Triangles:
2788 case PrimitiveMode::TriangleStrip:
2789 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002790 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002791
Jamie Madill493f9572018-05-24 19:52:15 -04002792 case PrimitiveMode::LinesAdjacency:
2793 case PrimitiveMode::LineStripAdjacency:
2794 case PrimitiveMode::TrianglesAdjacency:
2795 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002796 if (!extensions.geometryShader)
2797 {
Jamie Madille0472f32018-11-27 16:32:45 -05002798 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaofccebff2018-03-08 13:51:02 +08002799 return false;
2800 }
2801 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002802 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002803 context->validationError(GL_INVALID_ENUM, kInvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002804 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002805 }
2806
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002807 // If we are running GLES1, there is no current program.
2808 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002809 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002810 const State &state = context->getGLState();
2811
Jamie Madill785e8a02018-10-04 17:42:00 -04002812 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002813 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002814
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002815 // Do geometry shader specific validations
2816 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002817 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002818 if (!IsCompatibleDrawModeWithGeometryShader(
2819 mode, program->getGeometryShaderInputPrimitiveType()))
2820 {
Jamie Madill610640f2018-11-21 17:28:41 -05002821 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002822 kIncompatibleDrawModeAgainstGeometryShader);
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002823 return false;
2824 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002825 }
2826 }
2827
Jamie Madill9fdaa492018-02-16 10:52:11 -05002828 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002829}
2830
Jamie Madill5b772312018-03-08 20:28:32 -05002831bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002832 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002833 GLint first,
2834 GLsizei count,
2835 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002836{
Jamie Madillfd716582014-06-06 17:09:04 -04002837 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002838 {
Jamie Madille0472f32018-11-27 16:32:45 -05002839 context->validationError(GL_INVALID_VALUE, kNegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002840 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002841 }
2842
Jamie Madillf5c88e72018-12-08 09:56:38 -05002843 if (!ValidateDrawBase(context, mode, count))
Jamie Madill16e28fd2018-09-12 11:03:05 -04002844 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002845 return false;
2846 }
2847
Jamie Madill7f232932018-09-12 11:03:06 -04002848 const State &state = context->getGLState();
2849 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002850 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002851 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002852 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002853 if (!ValidateTransformFeedbackPrimitiveMode(context,
2854 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002855 {
Jamie Madille0472f32018-11-27 16:32:45 -05002856 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
James Darpinian30b604d2018-03-12 17:26:57 -07002857 return false;
2858 }
2859
2860 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2861 {
Jamie Madille0472f32018-11-27 16:32:45 -05002862 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferTooSmall);
James Darpinian30b604d2018-03-12 17:26:57 -07002863 return false;
2864 }
Jamie Madillfd716582014-06-06 17:09:04 -04002865 }
2866
Corentin Wallez71168a02016-12-19 15:11:18 -08002867 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002868 // - first < 0 has been checked as an error condition.
2869 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002870 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002871 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002872 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002873 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002874 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2875 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2876 {
Jamie Madille0472f32018-11-27 16:32:45 -05002877 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madill9fdaa492018-02-16 10:52:11 -05002878 return false;
2879 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002880
Jamie Madill2da53562018-08-01 11:34:47 -04002881 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002882 {
2883 return false;
2884 }
Jamie Madillfd716582014-06-06 17:09:04 -04002885 }
2886
2887 return true;
2888}
2889
He Yunchaoced53ae2016-11-29 15:00:51 +08002890bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002891 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002892 GLint first,
2893 GLsizei count,
2894 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002895{
Geoff Lang63c5a592017-09-27 14:08:16 -04002896 if (!context->getExtensions().instancedArrays)
2897 {
Jamie Madille0472f32018-11-27 16:32:45 -05002898 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002899 return false;
2900 }
2901
Corentin Wallez170efbf2017-05-02 13:45:01 -04002902 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002903 {
2904 return false;
2905 }
2906
Corentin Wallez0dc97812017-06-22 14:38:44 -04002907 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002908}
2909
Jamie Madill8dc27f92018-11-29 11:45:44 -05002910bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, DrawElementsType type)
Jamie Madillfd716582014-06-06 17:09:04 -04002911{
Jamie Madill8dc27f92018-11-29 11:45:44 -05002912 if (!context->getStateCache().isValidDrawElementsType(type))
Jamie Madill250d33f2014-06-06 17:09:03 -04002913 {
Jamie Madill8dc27f92018-11-29 11:45:44 -05002914 if (type == DrawElementsType::UnsignedInt)
2915 {
Jamie Madille0472f32018-11-27 16:32:45 -05002916 context->validationError(GL_INVALID_ENUM, kTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002917 return false;
Jamie Madill8dc27f92018-11-29 11:45:44 -05002918 }
2919
2920 ASSERT(type == DrawElementsType::InvalidEnum);
2921 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
2922 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002923 }
2924
Jamie Madillf5c88e72018-12-08 09:56:38 -05002925 // TODO(jmadill): Cache all of these into fast checks. http://anglebug.com/2966
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002926 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002927
Jamie Madill43da7c42018-08-01 11:34:49 -04002928 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002929 if (curTransformFeedback && curTransformFeedback->isActive() &&
2930 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002931 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002932 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2933 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2934 if (context->getExtensions().geometryShader)
2935 {
2936 if (!ValidateTransformFeedbackPrimitiveMode(
2937 context, curTransformFeedback->getPrimitiveMode(), mode))
2938 {
Jamie Madille0472f32018-11-27 16:32:45 -05002939 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002940 return false;
2941 }
2942 }
2943 else
2944 {
2945 // It is an invalid operation to call DrawElements, DrawRangeElements or
2946 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
2947 // 86)
Jamie Madill610640f2018-11-21 17:28:41 -05002948 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002949 kUnsupportedDrawModeForTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002950 return false;
2951 }
Jamie Madill250d33f2014-06-06 17:09:03 -04002952 }
2953
Jamie Madillf5c88e72018-12-08 09:56:38 -05002954 const VertexArray *vao = state.getVertexArray();
2955 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
2956
2957 if (elementArrayBuffer)
2958 {
2959 if (context->getExtensions().webglCompatibility)
2960 {
2961 if (elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
2962 {
2963 context->validationError(GL_INVALID_OPERATION,
2964 kElementArrayBufferBoundForTransformFeedback);
2965 return false;
2966 }
2967 }
2968 else if (elementArrayBuffer->isMapped())
2969 {
2970 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
2971 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the
2972 // WebGL 2.0 API. https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
2973 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
2974 return false;
2975 }
2976 }
2977 else
2978 {
2979 // [WebGL 1.0] Section 6.2 No Client Side Arrays
2980 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
2981 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
2982 if (!context->getGLState().areClientArraysEnabled() ||
2983 context->getExtensions().webglCompatibility)
2984 {
2985 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
2986 return false;
2987 }
2988 }
2989
Jiajia Qind9671222016-11-29 16:30:31 +08002990 return true;
2991}
2992
Jamie Madill5b772312018-03-08 20:28:32 -05002993bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002994 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002995 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05002996 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04002997 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002998 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08002999{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003000 if (!ValidateDrawElementsBase(context, mode, type))
Jamie Madillf5c88e72018-12-08 09:56:38 -05003001 {
Jiajia Qind9671222016-11-29 16:30:31 +08003002 return false;
Jamie Madillf5c88e72018-12-08 09:56:38 -05003003 }
Jiajia Qind9671222016-11-29 16:30:31 +08003004
Corentin Wallez170efbf2017-05-02 13:45:01 -04003005 if (!ValidateDrawBase(context, mode, count))
3006 {
3007 return false;
3008 }
3009
Jamie Madillf5c88e72018-12-08 09:56:38 -05003010 const State &state = context->getGLState();
Jamie Madill43da7c42018-08-01 11:34:49 -04003011 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003012 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003013
Jamie Madill8dc27f92018-11-29 11:45:44 -05003014 GLuint typeBytes = GetDrawElementsTypeSize(type);
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003015 ASSERT(isPow2(typeBytes) && typeBytes > 0);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003016
3017 if (context->getExtensions().webglCompatibility)
3018 {
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003019 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3020 {
3021 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3022 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3023 // data type passed to the call, or an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003024 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003025 return false;
3026 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003027
3028 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3029 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3030 // error is generated.
3031 if (reinterpret_cast<intptr_t>(indices) < 0)
3032 {
Jamie Madille0472f32018-11-27 16:32:45 -05003033 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003034 return false;
3035 }
Jamie Madillf5c88e72018-12-08 09:56:38 -05003036 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003037
Jamie Madillf5c88e72018-12-08 09:56:38 -05003038 // Early exit.
3039 if (count == 0)
3040 {
3041 return true;
3042 }
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003043
Jamie Madillf5c88e72018-12-08 09:56:38 -05003044 if (!elementArrayBuffer)
3045 {
3046 if (!indices)
James Darpiniane8a93c62018-01-04 18:02:24 -08003047 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003048 // This is an application error that would normally result in a crash, but we catch
3049 // it and return an error
3050 context->validationError(GL_INVALID_OPERATION, kElementArrayNoBufferOrPointer);
James Darpiniane8a93c62018-01-04 18:02:24 -08003051 return false;
3052 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003053 }
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003054 else
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003055 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003056 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3057 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3058 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3059 constexpr uint64_t kMaxTypeSize = 8;
3060 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3061 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3062 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3063
3064 uint64_t typeSize = typeBytes;
3065 uint64_t elementCount = static_cast<uint64_t>(count);
3066 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3067
3068 // Doing the multiplication here is overflow-safe
3069 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3070
3071 // The offset can be any value, check for overflows
3072 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3073 if (elementDataSizeNoOffset > kUint64Max - offset)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003074 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003075 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
3076 return false;
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003077 }
Jamie Madillf5c88e72018-12-08 09:56:38 -05003078
3079 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3080 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003081 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003082 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003083 return false;
3084 }
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003085 }
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003086
Jamie Madillf5c88e72018-12-08 09:56:38 -05003087 if (!context->getExtensions().robustBufferAccessBehavior && primcount > 0)
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003088 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003089 // Use the parameter buffer to retrieve and cache the index range.
3090 IndexRange indexRange;
3091 ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
3092
3093 // If we use an index greater than our maximum supported index range, return an error.
3094 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
3095 // always return an error if possible here.
3096 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003097 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003098 context->validationError(GL_INVALID_OPERATION, kExceedsMaxElement);
3099 return false;
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003100 }
3101
Jamie Madillf5c88e72018-12-08 09:56:38 -05003102 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003103 {
Jamie Madillf5c88e72018-12-08 09:56:38 -05003104 return false;
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003105 }
Jamie Madillf5c88e72018-12-08 09:56:38 -05003106
3107 // No op if there are no real indices in the index data (all are primitive restart).
3108 return (indexRange.vertexIndexCount > 0);
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003109 }
3110
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003111 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003112}
3113
Jamie Madill5b772312018-03-08 20:28:32 -05003114bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003115 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003116 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003117 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04003118 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003119 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003120{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003121 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003122}
3123
Geoff Lang3edfe032015-09-04 16:38:24 -04003124bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003125 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003126 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003127 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04003128 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003129 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003130{
Geoff Lang63c5a592017-09-27 14:08:16 -04003131 if (!context->getExtensions().instancedArrays)
3132 {
Jamie Madille0472f32018-11-27 16:32:45 -05003133 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04003134 return false;
3135 }
3136
Corentin Wallez170efbf2017-05-02 13:45:01 -04003137 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003138 {
3139 return false;
3140 }
3141
Corentin Wallez0dc97812017-06-22 14:38:44 -04003142 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003143}
3144
He Yunchaoced53ae2016-11-29 15:00:51 +08003145bool ValidateFramebufferTextureBase(Context *context,
3146 GLenum target,
3147 GLenum attachment,
3148 GLuint texture,
3149 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003150{
Geoff Lange8afa902017-09-27 15:00:43 -04003151 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003152 {
Jamie Madille0472f32018-11-27 16:32:45 -05003153 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003154 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003155 }
3156
3157 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003158 {
3159 return false;
3160 }
3161
Jamie Madill55ec3b12014-07-03 10:38:57 -04003162 if (texture != 0)
3163 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003164 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003165
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003166 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003167 {
Jamie Madille0472f32018-11-27 16:32:45 -05003168 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04003169 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003170 }
3171
3172 if (level < 0)
3173 {
Jamie Madille0472f32018-11-27 16:32:45 -05003174 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04003175 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003176 }
3177 }
3178
Jamie Madill43da7c42018-08-01 11:34:49 -04003179 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003180 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003181
Jamie Madill84115c92015-04-23 15:00:07 -04003182 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003183 {
Jamie Madille0472f32018-11-27 16:32:45 -05003184 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003185 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003186 }
3187
3188 return true;
3189}
3190
Geoff Langb1196682014-07-23 13:47:29 -04003191bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003192{
3193 if (program == 0)
3194 {
Jamie Madille0472f32018-11-27 16:32:45 -05003195 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04003196 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003197 }
3198
Jamie Madill43da7c42018-08-01 11:34:49 -04003199 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003200 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003201 {
3202 return false;
3203 }
3204
Jamie Madill0063c512014-08-25 15:47:53 -04003205 if (!programObject || !programObject->isLinked())
3206 {
Jamie Madille0472f32018-11-27 16:32:45 -05003207 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003208 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003209 }
3210
Geoff Lang7dd2e102014-11-10 15:19:26 -05003211 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003212 {
Jamie Madille0472f32018-11-27 16:32:45 -05003213 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003214 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003215 }
3216
Jamie Madill0063c512014-08-25 15:47:53 -04003217 return true;
3218}
3219
Geoff Langf41d0ee2016-10-07 13:04:23 -04003220static bool ValidateSizedGetUniform(Context *context,
3221 GLuint program,
3222 GLint location,
3223 GLsizei bufSize,
3224 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003225{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003226 if (length)
3227 {
3228 *length = 0;
3229 }
3230
Jamie Madill78f41802014-08-25 15:47:55 -04003231 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003232 {
Jamie Madill78f41802014-08-25 15:47:55 -04003233 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003234 }
3235
Geoff Langf41d0ee2016-10-07 13:04:23 -04003236 if (bufSize < 0)
3237 {
Jamie Madille0472f32018-11-27 16:32:45 -05003238 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003239 return false;
3240 }
3241
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003242 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003243 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003244
Jamie Madill78f41802014-08-25 15:47:55 -04003245 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003246 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003247 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003248 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003249 {
Jamie Madille0472f32018-11-27 16:32:45 -05003250 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003251 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003252 }
3253
Geoff Langf41d0ee2016-10-07 13:04:23 -04003254 if (length)
3255 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003256 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003257 }
3258
Jamie Madill0063c512014-08-25 15:47:53 -04003259 return true;
3260}
3261
He Yunchaoced53ae2016-11-29 15:00:51 +08003262bool ValidateGetnUniformfvEXT(Context *context,
3263 GLuint program,
3264 GLint location,
3265 GLsizei bufSize,
3266 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003267{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003268 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003269}
3270
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003271bool ValidateGetnUniformfvRobustANGLE(Context *context,
3272 GLuint program,
3273 GLint location,
3274 GLsizei bufSize,
3275 GLsizei *length,
3276 GLfloat *params)
3277{
3278 UNIMPLEMENTED();
3279 return false;
3280}
3281
He Yunchaoced53ae2016-11-29 15:00:51 +08003282bool ValidateGetnUniformivEXT(Context *context,
3283 GLuint program,
3284 GLint location,
3285 GLsizei bufSize,
3286 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003287{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003288 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3289}
3290
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003291bool ValidateGetnUniformivRobustANGLE(Context *context,
3292 GLuint program,
3293 GLint location,
3294 GLsizei bufSize,
3295 GLsizei *length,
3296 GLint *params)
3297{
3298 UNIMPLEMENTED();
3299 return false;
3300}
3301
3302bool ValidateGetnUniformuivRobustANGLE(Context *context,
3303 GLuint program,
3304 GLint location,
3305 GLsizei bufSize,
3306 GLsizei *length,
3307 GLuint *params)
3308{
3309 UNIMPLEMENTED();
3310 return false;
3311}
3312
Geoff Langf41d0ee2016-10-07 13:04:23 -04003313bool ValidateGetUniformfvRobustANGLE(Context *context,
3314 GLuint program,
3315 GLint location,
3316 GLsizei bufSize,
3317 GLsizei *length,
3318 GLfloat *params)
3319{
3320 if (!ValidateRobustEntryPoint(context, bufSize))
3321 {
3322 return false;
3323 }
3324
Brandon Jonesd1049182018-03-28 10:02:20 -07003325 GLsizei writeLength = 0;
3326
Geoff Langf41d0ee2016-10-07 13:04:23 -04003327 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003328 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3329 {
3330 return false;
3331 }
3332
3333 SetRobustLengthParam(length, writeLength);
3334
3335 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003336}
3337
3338bool ValidateGetUniformivRobustANGLE(Context *context,
3339 GLuint program,
3340 GLint location,
3341 GLsizei bufSize,
3342 GLsizei *length,
3343 GLint *params)
3344{
3345 if (!ValidateRobustEntryPoint(context, bufSize))
3346 {
3347 return false;
3348 }
3349
Brandon Jonesd1049182018-03-28 10:02:20 -07003350 GLsizei writeLength = 0;
3351
Geoff Langf41d0ee2016-10-07 13:04:23 -04003352 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003353 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3354 {
3355 return false;
3356 }
3357
3358 SetRobustLengthParam(length, writeLength);
3359
3360 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003361}
3362
3363bool ValidateGetUniformuivRobustANGLE(Context *context,
3364 GLuint program,
3365 GLint location,
3366 GLsizei bufSize,
3367 GLsizei *length,
3368 GLuint *params)
3369{
3370 if (!ValidateRobustEntryPoint(context, bufSize))
3371 {
3372 return false;
3373 }
3374
3375 if (context->getClientMajorVersion() < 3)
3376 {
Jamie Madille0472f32018-11-27 16:32:45 -05003377 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003378 return false;
3379 }
3380
Brandon Jonesd1049182018-03-28 10:02:20 -07003381 GLsizei writeLength = 0;
3382
Geoff Langf41d0ee2016-10-07 13:04:23 -04003383 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003384 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3385 {
3386 return false;
3387 }
3388
3389 SetRobustLengthParam(length, writeLength);
3390
3391 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003392}
3393
He Yunchaoced53ae2016-11-29 15:00:51 +08003394bool ValidateDiscardFramebufferBase(Context *context,
3395 GLenum target,
3396 GLsizei numAttachments,
3397 const GLenum *attachments,
3398 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003399{
3400 if (numAttachments < 0)
3401 {
Jamie Madille0472f32018-11-27 16:32:45 -05003402 context->validationError(GL_INVALID_VALUE, kNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003403 return false;
3404 }
3405
3406 for (GLsizei i = 0; i < numAttachments; ++i)
3407 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003408 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003409 {
3410 if (defaultFramebuffer)
3411 {
Jamie Madille0472f32018-11-27 16:32:45 -05003412 context->validationError(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003413 return false;
3414 }
3415
3416 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3417 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003418 context->validationError(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003419 return false;
3420 }
3421 }
3422 else
3423 {
3424 switch (attachments[i])
3425 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003426 case GL_DEPTH_ATTACHMENT:
3427 case GL_STENCIL_ATTACHMENT:
3428 case GL_DEPTH_STENCIL_ATTACHMENT:
3429 if (defaultFramebuffer)
3430 {
Jamie Madill610640f2018-11-21 17:28:41 -05003431 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003432 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003433 return false;
3434 }
3435 break;
3436 case GL_COLOR:
3437 case GL_DEPTH:
3438 case GL_STENCIL:
3439 if (!defaultFramebuffer)
3440 {
Jamie Madill610640f2018-11-21 17:28:41 -05003441 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003442 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003443 return false;
3444 }
3445 break;
3446 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003447 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003448 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003449 }
3450 }
3451 }
3452
3453 return true;
3454}
3455
Austin Kinross6ee1e782015-05-29 17:05:37 -07003456bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3457{
Jamie Madill007530e2017-12-28 14:27:04 -05003458 if (!context->getExtensions().debugMarker)
3459 {
3460 // The debug marker calls should not set error state
3461 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003462 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003463 return false;
3464 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003465
Jamie Madill007530e2017-12-28 14:27:04 -05003466 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003467 if (length < 0)
3468 {
3469 return false;
3470 }
3471
3472 if (marker == nullptr)
3473 {
3474 return false;
3475 }
3476
3477 return true;
3478}
3479
3480bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3481{
Jamie Madill007530e2017-12-28 14:27:04 -05003482 if (!context->getExtensions().debugMarker)
3483 {
3484 // The debug marker calls should not set error state
3485 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003486 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003487 return false;
3488 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003489
Jamie Madill007530e2017-12-28 14:27:04 -05003490 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003491 if (length < 0)
3492 {
3493 return false;
3494 }
3495
3496 if (length > 0 && marker == nullptr)
3497 {
3498 return false;
3499 }
3500
3501 return true;
3502}
3503
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003504bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003505{
Geoff Langa8406172015-07-21 16:53:39 -04003506 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3507 {
Jamie Madille0472f32018-11-27 16:32:45 -05003508 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003509 return false;
3510 }
3511
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003512 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003513 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003514 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003515 if (!context->getExtensions().eglImage)
3516 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003517 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb66a9092016-05-16 15:59:14 -04003518 }
3519 break;
3520
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003521 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003522 if (!context->getExtensions().eglImageExternal)
3523 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003524 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb66a9092016-05-16 15:59:14 -04003525 }
Geoff Langa8406172015-07-21 16:53:39 -04003526 break;
3527
3528 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003529 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003530 return false;
3531 }
3532
Rafael Cintron05a449a2018-06-20 18:08:04 -07003533 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003534
Jamie Madill61e16b42017-06-19 11:13:23 -04003535 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003536 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003537 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003538 context->validationError(GL_INVALID_VALUE, kInvalidEGLImage);
Geoff Langa8406172015-07-21 16:53:39 -04003539 return false;
3540 }
3541
Jamie Madill007530e2017-12-28 14:27:04 -05003542 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003543 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003544 context->validationError(GL_INVALID_OPERATION, kEGLImageCannotCreate2DMultisampled);
Geoff Langa8406172015-07-21 16:53:39 -04003545 return false;
3546 }
3547
Yuly Novikov2eb54072018-08-22 16:41:26 -04003548 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003549 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003550 context->validationError(GL_INVALID_OPERATION, kEGLImageTextureFormatNotSupported);
Geoff Langa8406172015-07-21 16:53:39 -04003551 return false;
3552 }
3553
Geoff Langdcab33b2015-07-21 13:03:16 -04003554 return true;
3555}
3556
3557bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003558 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003559 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003560{
Geoff Langa8406172015-07-21 16:53:39 -04003561 if (!context->getExtensions().eglImage)
3562 {
Jamie Madille0472f32018-11-27 16:32:45 -05003563 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003564 return false;
3565 }
3566
3567 switch (target)
3568 {
3569 case GL_RENDERBUFFER:
3570 break;
3571
3572 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003573 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003574 return false;
3575 }
3576
Rafael Cintron05a449a2018-06-20 18:08:04 -07003577 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003578
Jamie Madill61e16b42017-06-19 11:13:23 -04003579 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003580 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003581 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003582 context->validationError(GL_INVALID_VALUE, kInvalidEGLImage);
Geoff Langa8406172015-07-21 16:53:39 -04003583 return false;
3584 }
3585
Yuly Novikov2eb54072018-08-22 16:41:26 -04003586 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003587 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003588 context->validationError(GL_INVALID_OPERATION, kEGLImageRenderbufferFormatNotSupported);
Geoff Langa8406172015-07-21 16:53:39 -04003589 return false;
3590 }
3591
Geoff Langdcab33b2015-07-21 13:03:16 -04003592 return true;
3593}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003594
3595bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3596{
Geoff Lang36167ab2015-12-07 10:27:14 -05003597 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003598 {
3599 // The default VAO should always exist
3600 ASSERT(array != 0);
Jamie Madille0472f32018-11-27 16:32:45 -05003601 context->validationError(GL_INVALID_OPERATION, kInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003602 return false;
3603 }
3604
3605 return true;
3606}
3607
Geoff Langc5629752015-12-07 16:29:04 -05003608bool ValidateProgramBinaryBase(Context *context,
3609 GLuint program,
3610 GLenum binaryFormat,
3611 const void *binary,
3612 GLint length)
3613{
3614 Program *programObject = GetValidProgram(context, program);
3615 if (programObject == nullptr)
3616 {
3617 return false;
3618 }
3619
3620 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3621 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3622 programBinaryFormats.end())
3623 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003624 context->validationError(GL_INVALID_ENUM, kInvalidProgramBinaryFormat);
Geoff Langc5629752015-12-07 16:29:04 -05003625 return false;
3626 }
3627
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003628 if (context->hasActiveTransformFeedback(program))
3629 {
3630 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05003631 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackProgramBinary);
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003632 return false;
3633 }
3634
Geoff Langc5629752015-12-07 16:29:04 -05003635 return true;
3636}
3637
3638bool ValidateGetProgramBinaryBase(Context *context,
3639 GLuint program,
3640 GLsizei bufSize,
3641 GLsizei *length,
3642 GLenum *binaryFormat,
3643 void *binary)
3644{
3645 Program *programObject = GetValidProgram(context, program);
3646 if (programObject == nullptr)
3647 {
3648 return false;
3649 }
3650
3651 if (!programObject->isLinked())
3652 {
Jamie Madille0472f32018-11-27 16:32:45 -05003653 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003654 return false;
3655 }
3656
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003657 if (context->getCaps().programBinaryFormats.empty())
3658 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003659 context->validationError(GL_INVALID_OPERATION, kNoProgramBinaryFormats);
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003660 return false;
3661 }
3662
Geoff Langc5629752015-12-07 16:29:04 -05003663 return true;
3664}
Jamie Madillc29968b2016-01-20 11:17:23 -05003665
Jamie Madill5b772312018-03-08 20:28:32 -05003666bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003667{
3668 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003669 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003670 {
Jamie Madille0472f32018-11-27 16:32:45 -05003671 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003672 return false;
3673 }
3674 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3675 {
Jamie Madille0472f32018-11-27 16:32:45 -05003676 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003677 return false;
3678 }
3679
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003680 ASSERT(context->getGLState().getDrawFramebuffer());
3681 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003682 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3683
3684 // This should come first before the check for the default frame buffer
3685 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3686 // rather than INVALID_OPERATION
3687 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3688 {
3689 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3690
3691 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003692 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3693 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003694 {
3695 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003696 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3697 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3698 // 3.1 is still a bit ambiguous about the error, but future specs are
3699 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madillc3e37312018-11-30 15:25:39 -05003700 context->validationError(GL_INVALID_ENUM, kInvalidDrawBuffer);
Olli Etuaho84c9f592016-03-09 14:37:25 +02003701 return false;
3702 }
3703 else if (bufs[colorAttachment] >= maxColorAttachment)
3704 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003705 context->validationError(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
Jamie Madillc29968b2016-01-20 11:17:23 -05003706 return false;
3707 }
3708 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3709 frameBufferId != 0)
3710 {
3711 // INVALID_OPERATION-GL is bound to buffer and ith argument
3712 // is not COLOR_ATTACHMENTi or NONE
Jamie Madillc3e37312018-11-30 15:25:39 -05003713 context->validationError(GL_INVALID_OPERATION, kInvalidDrawBufferValue);
Jamie Madillc29968b2016-01-20 11:17:23 -05003714 return false;
3715 }
3716 }
3717
3718 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3719 // and n is not 1 or bufs is bound to value other than BACK and NONE
3720 if (frameBufferId == 0)
3721 {
3722 if (n != 1)
3723 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003724 context->validationError(GL_INVALID_OPERATION, kInvalidDrawBufferCountForDefault);
Jamie Madillc29968b2016-01-20 11:17:23 -05003725 return false;
3726 }
3727
3728 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3729 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003730 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferInvalidDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003731 return false;
3732 }
3733 }
3734
3735 return true;
3736}
3737
Geoff Lang496c02d2016-10-20 11:38:11 -07003738bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003739 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003740 GLenum pname,
3741 GLsizei *length,
3742 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003743{
Geoff Lang496c02d2016-10-20 11:38:11 -07003744 if (length)
3745 {
3746 *length = 0;
3747 }
3748
Corentin Walleze4477002017-12-01 14:39:58 -05003749 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003750 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003751 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003752 return false;
3753 }
3754
Geoff Lang496c02d2016-10-20 11:38:11 -07003755 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003756 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003757 case GL_BUFFER_MAP_POINTER:
3758 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003759
Geoff Lang496c02d2016-10-20 11:38:11 -07003760 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003761 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003762 return false;
3763 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003764
3765 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3766 // target bound to zero generate an INVALID_OPERATION error."
3767 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003768 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003769 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003770 context->validationError(GL_INVALID_OPERATION, kBufferPointerNotAvailable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003771 return false;
3772 }
3773
Geoff Lang496c02d2016-10-20 11:38:11 -07003774 if (length)
3775 {
3776 *length = 1;
3777 }
3778
Olli Etuaho4f667482016-03-30 15:56:35 +03003779 return true;
3780}
3781
Corentin Wallez336129f2017-10-17 15:55:40 -04003782bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003783{
Corentin Walleze4477002017-12-01 14:39:58 -05003784 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003785 {
Jamie Madille0472f32018-11-27 16:32:45 -05003786 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003787 return false;
3788 }
3789
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003790 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003791
3792 if (buffer == nullptr || !buffer->isMapped())
3793 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003794 context->validationError(GL_INVALID_OPERATION, kBufferNotMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003795 return false;
3796 }
3797
3798 return true;
3799}
3800
3801bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003802 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003803 GLintptr offset,
3804 GLsizeiptr length,
3805 GLbitfield access)
3806{
Corentin Walleze4477002017-12-01 14:39:58 -05003807 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003808 {
Jamie Madille0472f32018-11-27 16:32:45 -05003809 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003810 return false;
3811 }
3812
Brandon Jones6cad5662017-06-14 13:25:13 -07003813 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003814 {
Jamie Madille0472f32018-11-27 16:32:45 -05003815 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003816 return false;
3817 }
3818
3819 if (length < 0)
3820 {
Jamie Madille0472f32018-11-27 16:32:45 -05003821 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003822 return false;
3823 }
3824
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003825 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003826
3827 if (!buffer)
3828 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003829 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003830 return false;
3831 }
3832
3833 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003834 CheckedNumeric<size_t> checkedOffset(offset);
3835 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003836
Jamie Madille2e406c2016-06-02 13:04:10 -04003837 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003838 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003839 context->validationError(GL_INVALID_VALUE, kMapOutOfRange);
Olli Etuaho4f667482016-03-30 15:56:35 +03003840 return false;
3841 }
3842
3843 // Check for invalid bits in the mask
3844 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3845 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3846 GL_MAP_UNSYNCHRONIZED_BIT;
3847
3848 if (access & ~(allAccessBits))
3849 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003850 context->validationError(GL_INVALID_VALUE, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003851 return false;
3852 }
3853
3854 if (length == 0)
3855 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003856 context->validationError(GL_INVALID_OPERATION, kLengthZero);
Olli Etuaho4f667482016-03-30 15:56:35 +03003857 return false;
3858 }
3859
3860 if (buffer->isMapped())
3861 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003862 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003863 return false;
3864 }
3865
3866 // Check for invalid bit combinations
3867 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3868 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003869 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite);
Olli Etuaho4f667482016-03-30 15:56:35 +03003870 return false;
3871 }
3872
3873 GLbitfield writeOnlyBits =
3874 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3875
3876 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3877 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003878 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsRead);
Olli Etuaho4f667482016-03-30 15:56:35 +03003879 return false;
3880 }
3881
3882 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3883 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003884 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsFlush);
Olli Etuaho4f667482016-03-30 15:56:35 +03003885 return false;
3886 }
Geoff Lang79f71042017-08-14 16:43:43 -04003887
3888 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003889}
3890
3891bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003892 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003893 GLintptr offset,
3894 GLsizeiptr length)
3895{
Brandon Jones6cad5662017-06-14 13:25:13 -07003896 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003897 {
Jamie Madille0472f32018-11-27 16:32:45 -05003898 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003899 return false;
3900 }
3901
3902 if (length < 0)
3903 {
Jamie Madille0472f32018-11-27 16:32:45 -05003904 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003905 return false;
3906 }
3907
Corentin Walleze4477002017-12-01 14:39:58 -05003908 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003909 {
Jamie Madille0472f32018-11-27 16:32:45 -05003910 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003911 return false;
3912 }
3913
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003914 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003915
3916 if (buffer == nullptr)
3917 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003918 context->validationError(GL_INVALID_OPERATION, kInvalidFlushZero);
Olli Etuaho4f667482016-03-30 15:56:35 +03003919 return false;
3920 }
3921
3922 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
3923 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003924 context->validationError(GL_INVALID_OPERATION, kInvalidFlushTarget);
Olli Etuaho4f667482016-03-30 15:56:35 +03003925 return false;
3926 }
3927
3928 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003929 CheckedNumeric<size_t> checkedOffset(offset);
3930 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003931
Jamie Madille2e406c2016-06-02 13:04:10 -04003932 if (!checkedSize.IsValid() ||
3933 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003934 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003935 context->validationError(GL_INVALID_VALUE, kInvalidFlushOutOfRange);
Olli Etuaho4f667482016-03-30 15:56:35 +03003936 return false;
3937 }
3938
3939 return true;
3940}
3941
Olli Etuaho41997e72016-03-10 13:38:39 +02003942bool ValidateGenOrDelete(Context *context, GLint n)
3943{
3944 if (n < 0)
3945 {
Jamie Madille0472f32018-11-27 16:32:45 -05003946 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02003947 return false;
3948 }
3949 return true;
3950}
3951
Jamie Madill5b772312018-03-08 20:28:32 -05003952bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04003953{
3954 if (!context->getExtensions().robustClientMemory)
3955 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003956 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langff5b2d52016-09-07 11:32:23 -04003957 return false;
3958 }
3959
3960 if (bufSize < 0)
3961 {
Jamie Madille0472f32018-11-27 16:32:45 -05003962 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04003963 return false;
3964 }
3965
3966 return true;
3967}
3968
Jamie Madill5b772312018-03-08 20:28:32 -05003969bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04003970{
3971 if (bufSize < numParams)
3972 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003973 context->validationError(GL_INVALID_OPERATION, kInsufficientParams);
Geoff Lang2e43dbb2016-10-14 12:27:35 -04003974 return false;
3975 }
3976
3977 return true;
3978}
3979
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08003980bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04003981 GLenum target,
3982 GLenum attachment,
3983 GLenum pname,
3984 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04003985{
Geoff Lange8afa902017-09-27 15:00:43 -04003986 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04003987 {
Jamie Madille0472f32018-11-27 16:32:45 -05003988 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04003989 return false;
3990 }
3991
3992 int clientVersion = context->getClientMajorVersion();
3993
3994 switch (pname)
3995 {
3996 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3997 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3998 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3999 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4000 break;
4001
Martin Radeve5285d22017-07-14 16:23:53 +03004002 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4003 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4004 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4005 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4006 if (clientVersion < 3 || !context->getExtensions().multiview)
4007 {
Jamie Madille0472f32018-11-27 16:32:45 -05004008 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03004009 return false;
4010 }
4011 break;
4012
Geoff Langff5b2d52016-09-07 11:32:23 -04004013 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4014 if (clientVersion < 3 && !context->getExtensions().sRGB)
4015 {
Jamie Madille0472f32018-11-27 16:32:45 -05004016 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004017 return false;
4018 }
4019 break;
4020
4021 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4022 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4023 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4024 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4025 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4026 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4027 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4028 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4029 if (clientVersion < 3)
4030 {
Jamie Madille0472f32018-11-27 16:32:45 -05004031 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004032 return false;
4033 }
4034 break;
4035
Jiawei Shaoa8802472018-05-28 11:17:47 +08004036 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4037 if (!context->getExtensions().geometryShader)
4038 {
Jamie Madille0472f32018-11-27 16:32:45 -05004039 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08004040 return false;
4041 }
4042 break;
4043
Geoff Langff5b2d52016-09-07 11:32:23 -04004044 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004045 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04004046 return false;
4047 }
4048
4049 // Determine if the attachment is a valid enum
4050 switch (attachment)
4051 {
4052 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004053 case GL_DEPTH:
4054 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004055 if (clientVersion < 3)
4056 {
Jamie Madille0472f32018-11-27 16:32:45 -05004057 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004058 return false;
4059 }
4060 break;
4061
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004062 case GL_DEPTH_STENCIL_ATTACHMENT:
4063 if (clientVersion < 3 && !context->isWebGL1())
4064 {
Jamie Madille0472f32018-11-27 16:32:45 -05004065 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004066 return false;
4067 }
4068 break;
4069
Geoff Langfa125c92017-10-24 13:01:46 -04004070 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004071 case GL_DEPTH_ATTACHMENT:
4072 case GL_STENCIL_ATTACHMENT:
4073 break;
4074
4075 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004076 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4077 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004078 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4079 {
Jamie Madille0472f32018-11-27 16:32:45 -05004080 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004081 return false;
4082 }
4083 break;
4084 }
4085
4086 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4087 ASSERT(framebuffer);
4088
4089 if (framebuffer->id() == 0)
4090 {
4091 if (clientVersion < 3)
4092 {
Jamie Madille0472f32018-11-27 16:32:45 -05004093 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004094 return false;
4095 }
4096
4097 switch (attachment)
4098 {
4099 case GL_BACK:
4100 case GL_DEPTH:
4101 case GL_STENCIL:
4102 break;
4103
4104 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004105 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004106 return false;
4107 }
4108 }
4109 else
4110 {
4111 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4112 {
4113 // Valid attachment query
4114 }
4115 else
4116 {
4117 switch (attachment)
4118 {
4119 case GL_DEPTH_ATTACHMENT:
4120 case GL_STENCIL_ATTACHMENT:
4121 break;
4122
4123 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004124 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004125 {
Jamie Madille0472f32018-11-27 16:32:45 -05004126 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004127 return false;
4128 }
4129 break;
4130
4131 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004132 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004133 return false;
4134 }
4135 }
4136 }
4137
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004138 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004139 if (attachmentObject)
4140 {
4141 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4142 attachmentObject->type() == GL_TEXTURE ||
4143 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4144
4145 switch (pname)
4146 {
4147 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4148 if (attachmentObject->type() != GL_RENDERBUFFER &&
4149 attachmentObject->type() != GL_TEXTURE)
4150 {
Jamie Madille0472f32018-11-27 16:32:45 -05004151 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004152 return false;
4153 }
4154 break;
4155
4156 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4157 if (attachmentObject->type() != GL_TEXTURE)
4158 {
Jamie Madille0472f32018-11-27 16:32:45 -05004159 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004160 return false;
4161 }
4162 break;
4163
4164 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4165 if (attachmentObject->type() != GL_TEXTURE)
4166 {
Jamie Madille0472f32018-11-27 16:32:45 -05004167 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004168 return false;
4169 }
4170 break;
4171
4172 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4173 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4174 {
Jamie Madille0472f32018-11-27 16:32:45 -05004175 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004176 return false;
4177 }
4178 break;
4179
4180 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4181 if (attachmentObject->type() != GL_TEXTURE)
4182 {
Jamie Madille0472f32018-11-27 16:32:45 -05004183 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004184 return false;
4185 }
4186 break;
4187
4188 default:
4189 break;
4190 }
4191 }
4192 else
4193 {
4194 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4195 // is NONE, then querying any other pname will generate INVALID_ENUM.
4196
4197 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4198 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4199 // INVALID_OPERATION for all other pnames
4200
4201 switch (pname)
4202 {
4203 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4204 break;
4205
4206 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4207 if (clientVersion < 3)
4208 {
Jamie Madill610640f2018-11-21 17:28:41 -05004209 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004210 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004211 return false;
4212 }
4213 break;
4214
4215 default:
4216 if (clientVersion < 3)
4217 {
Jamie Madill610640f2018-11-21 17:28:41 -05004218 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004219 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004220 return false;
4221 }
4222 else
4223 {
Jamie Madill610640f2018-11-21 17:28:41 -05004224 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05004225 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004226 return false;
4227 }
4228 }
4229 }
4230
Martin Radeve5285d22017-07-14 16:23:53 +03004231 if (numParams)
4232 {
4233 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4234 {
4235 // Only when the viewport offsets are queried we can have a varying number of output
4236 // parameters.
4237 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4238 *numParams = numViews * 2;
4239 }
4240 else
4241 {
4242 // For all other queries we can have only one output parameter.
4243 *numParams = 1;
4244 }
4245 }
4246
Geoff Langff5b2d52016-09-07 11:32:23 -04004247 return true;
4248}
4249
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004250bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004251 GLenum target,
4252 GLenum attachment,
4253 GLenum pname,
4254 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004255 GLsizei *length,
4256 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004257{
4258 if (!ValidateRobustEntryPoint(context, bufSize))
4259 {
4260 return false;
4261 }
4262
Brandon Jonesd1049182018-03-28 10:02:20 -07004263 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004264 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004265 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004266 {
4267 return false;
4268 }
4269
Brandon Jonesd1049182018-03-28 10:02:20 -07004270 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004271 {
4272 return false;
4273 }
4274
Brandon Jonesd1049182018-03-28 10:02:20 -07004275 SetRobustLengthParam(length, numParams);
4276
Geoff Langff5b2d52016-09-07 11:32:23 -04004277 return true;
4278}
4279
Jamie Madill5b772312018-03-08 20:28:32 -05004280bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004281 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004282 GLenum pname,
4283 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004284 GLsizei *length,
4285 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004286{
4287 if (!ValidateRobustEntryPoint(context, bufSize))
4288 {
4289 return false;
4290 }
4291
Brandon Jonesd1049182018-03-28 10:02:20 -07004292 GLsizei numParams = 0;
4293
4294 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004295 {
4296 return false;
4297 }
4298
Brandon Jonesd1049182018-03-28 10:02:20 -07004299 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004300 {
4301 return false;
4302 }
4303
Brandon Jonesd1049182018-03-28 10:02:20 -07004304 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004305 return true;
4306}
4307
Jamie Madill5b772312018-03-08 20:28:32 -05004308bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004309 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004310 GLenum pname,
4311 GLsizei bufSize,
4312 GLsizei *length,
4313 GLint64 *params)
4314{
Brandon Jonesd1049182018-03-28 10:02:20 -07004315 GLsizei numParams = 0;
4316
Geoff Langebebe1c2016-10-14 12:01:31 -04004317 if (!ValidateRobustEntryPoint(context, bufSize))
4318 {
4319 return false;
4320 }
4321
Brandon Jonesd1049182018-03-28 10:02:20 -07004322 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004323 {
4324 return false;
4325 }
4326
Brandon Jonesd1049182018-03-28 10:02:20 -07004327 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004328 {
4329 return false;
4330 }
4331
Brandon Jonesd1049182018-03-28 10:02:20 -07004332 SetRobustLengthParam(length, numParams);
4333
Geoff Langff5b2d52016-09-07 11:32:23 -04004334 return true;
4335}
4336
Jamie Madill5b772312018-03-08 20:28:32 -05004337bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004338{
4339 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004340 if (numParams)
4341 {
4342 *numParams = 1;
4343 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004344
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004345 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4346 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4347 ? GetValidProgramNoResolve(context, program)
4348 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004349 if (!programObject)
4350 {
4351 return false;
4352 }
4353
4354 switch (pname)
4355 {
4356 case GL_DELETE_STATUS:
4357 case GL_LINK_STATUS:
4358 case GL_VALIDATE_STATUS:
4359 case GL_INFO_LOG_LENGTH:
4360 case GL_ATTACHED_SHADERS:
4361 case GL_ACTIVE_ATTRIBUTES:
4362 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4363 case GL_ACTIVE_UNIFORMS:
4364 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4365 break;
4366
4367 case GL_PROGRAM_BINARY_LENGTH:
4368 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4369 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004370 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004371 return false;
4372 }
4373 break;
4374
4375 case GL_ACTIVE_UNIFORM_BLOCKS:
4376 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4377 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4378 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4379 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4380 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4381 if (context->getClientMajorVersion() < 3)
4382 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004383 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Geoff Langff5b2d52016-09-07 11:32:23 -04004384 return false;
4385 }
4386 break;
4387
Yunchao He61afff12017-03-14 15:34:03 +08004388 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004389 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004390 if (context->getClientVersion() < Version(3, 1))
4391 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004392 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao He61afff12017-03-14 15:34:03 +08004393 return false;
4394 }
4395 break;
4396
Jiawei Shao6ae51612018-02-23 14:03:25 +08004397 case GL_COMPUTE_WORK_GROUP_SIZE:
4398 if (context->getClientVersion() < Version(3, 1))
4399 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004400 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004401 return false;
4402 }
4403
4404 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4405 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4406 // program which has not been linked successfully, or which does not contain objects to
4407 // form a compute shader.
4408 if (!programObject->isLinked())
4409 {
Jamie Madille0472f32018-11-27 16:32:45 -05004410 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004411 return false;
4412 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004413 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004414 {
Jamie Madille0472f32018-11-27 16:32:45 -05004415 context->validationError(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004416 return false;
4417 }
4418 break;
4419
Jiawei Shao447bfac2018-03-14 14:23:40 +08004420 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4421 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4422 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4423 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4424 if (!context->getExtensions().geometryShader)
4425 {
Jamie Madille0472f32018-11-27 16:32:45 -05004426 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004427 return false;
4428 }
4429
4430 // [EXT_geometry_shader] Chapter 7.12
4431 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4432 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4433 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4434 // successfully, or which does not contain objects to form a geometry shader.
4435 if (!programObject->isLinked())
4436 {
Jamie Madille0472f32018-11-27 16:32:45 -05004437 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004438 return false;
4439 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004440 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004441 {
Jamie Madille0472f32018-11-27 16:32:45 -05004442 context->validationError(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004443 return false;
4444 }
4445 break;
4446
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004447 case GL_COMPLETION_STATUS_KHR:
4448 if (!context->getExtensions().parallelShaderCompile)
4449 {
Jamie Madille0472f32018-11-27 16:32:45 -05004450 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004451 return false;
4452 }
4453 break;
4454
Geoff Langff5b2d52016-09-07 11:32:23 -04004455 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004456 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004457 return false;
4458 }
4459
4460 return true;
4461}
4462
4463bool ValidateGetProgramivRobustANGLE(Context *context,
4464 GLuint program,
4465 GLenum pname,
4466 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004467 GLsizei *length,
4468 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004469{
4470 if (!ValidateRobustEntryPoint(context, bufSize))
4471 {
4472 return false;
4473 }
4474
Brandon Jonesd1049182018-03-28 10:02:20 -07004475 GLsizei numParams = 0;
4476
4477 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004478 {
4479 return false;
4480 }
4481
Brandon Jonesd1049182018-03-28 10:02:20 -07004482 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004483 {
4484 return false;
4485 }
4486
Brandon Jonesd1049182018-03-28 10:02:20 -07004487 SetRobustLengthParam(length, numParams);
4488
Geoff Langff5b2d52016-09-07 11:32:23 -04004489 return true;
4490}
4491
Geoff Lang740d9022016-10-07 11:20:52 -04004492bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4493 GLenum target,
4494 GLenum pname,
4495 GLsizei bufSize,
4496 GLsizei *length,
4497 GLint *params)
4498{
4499 if (!ValidateRobustEntryPoint(context, bufSize))
4500 {
4501 return false;
4502 }
4503
Brandon Jonesd1049182018-03-28 10:02:20 -07004504 GLsizei numParams = 0;
4505
4506 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004507 {
4508 return false;
4509 }
4510
Brandon Jonesd1049182018-03-28 10:02:20 -07004511 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004512 {
4513 return false;
4514 }
4515
Brandon Jonesd1049182018-03-28 10:02:20 -07004516 SetRobustLengthParam(length, numParams);
4517
Geoff Lang740d9022016-10-07 11:20:52 -04004518 return true;
4519}
4520
Geoff Langd7d0ed32016-10-07 11:33:51 -04004521bool ValidateGetShaderivRobustANGLE(Context *context,
4522 GLuint shader,
4523 GLenum pname,
4524 GLsizei bufSize,
4525 GLsizei *length,
4526 GLint *params)
4527{
4528 if (!ValidateRobustEntryPoint(context, bufSize))
4529 {
4530 return false;
4531 }
4532
Brandon Jonesd1049182018-03-28 10:02:20 -07004533 GLsizei numParams = 0;
4534
4535 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004536 {
4537 return false;
4538 }
4539
Brandon Jonesd1049182018-03-28 10:02:20 -07004540 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004541 {
4542 return false;
4543 }
4544
Brandon Jonesd1049182018-03-28 10:02:20 -07004545 SetRobustLengthParam(length, numParams);
4546
Geoff Langd7d0ed32016-10-07 11:33:51 -04004547 return true;
4548}
4549
Geoff Langc1984ed2016-10-07 12:41:00 -04004550bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004551 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004552 GLenum pname,
4553 GLsizei bufSize,
4554 GLsizei *length,
4555 GLfloat *params)
4556{
4557 if (!ValidateRobustEntryPoint(context, bufSize))
4558 {
4559 return false;
4560 }
4561
Brandon Jonesd1049182018-03-28 10:02:20 -07004562 GLsizei numParams = 0;
4563
4564 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004565 {
4566 return false;
4567 }
4568
Brandon Jonesd1049182018-03-28 10:02:20 -07004569 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004570 {
4571 return false;
4572 }
4573
Brandon Jonesd1049182018-03-28 10:02:20 -07004574 SetRobustLengthParam(length, numParams);
4575
Geoff Langc1984ed2016-10-07 12:41:00 -04004576 return true;
4577}
4578
Geoff Langc1984ed2016-10-07 12:41:00 -04004579bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004580 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004581 GLenum pname,
4582 GLsizei bufSize,
4583 GLsizei *length,
4584 GLint *params)
4585{
Brandon Jonesd1049182018-03-28 10:02:20 -07004586
Geoff Langc1984ed2016-10-07 12:41:00 -04004587 if (!ValidateRobustEntryPoint(context, bufSize))
4588 {
4589 return false;
4590 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004591 GLsizei numParams = 0;
4592 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004593 {
4594 return false;
4595 }
4596
Brandon Jonesd1049182018-03-28 10:02:20 -07004597 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004598 {
4599 return false;
4600 }
4601
Brandon Jonesd1049182018-03-28 10:02:20 -07004602 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004603 return true;
4604}
4605
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004606bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4607 TextureType target,
4608 GLenum pname,
4609 GLsizei bufSize,
4610 GLsizei *length,
4611 GLint *params)
4612{
4613 UNIMPLEMENTED();
4614 return false;
4615}
4616
4617bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4618 TextureType target,
4619 GLenum pname,
4620 GLsizei bufSize,
4621 GLsizei *length,
4622 GLuint *params)
4623{
4624 UNIMPLEMENTED();
4625 return false;
4626}
4627
Geoff Langc1984ed2016-10-07 12:41:00 -04004628bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004629 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004630 GLenum pname,
4631 GLsizei bufSize,
4632 const GLfloat *params)
4633{
4634 if (!ValidateRobustEntryPoint(context, bufSize))
4635 {
4636 return false;
4637 }
4638
Till Rathmannb8543632018-10-02 19:46:14 +02004639 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004640}
4641
Geoff Langc1984ed2016-10-07 12:41:00 -04004642bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004643 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004644 GLenum pname,
4645 GLsizei bufSize,
4646 const GLint *params)
4647{
4648 if (!ValidateRobustEntryPoint(context, bufSize))
4649 {
4650 return false;
4651 }
4652
Till Rathmannb8543632018-10-02 19:46:14 +02004653 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004654}
4655
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004656bool ValidateTexParameterIivRobustANGLE(Context *context,
4657 TextureType target,
4658 GLenum pname,
4659 GLsizei bufSize,
4660 const GLint *params)
4661{
4662 UNIMPLEMENTED();
4663 return false;
4664}
4665
4666bool ValidateTexParameterIuivRobustANGLE(Context *context,
4667 TextureType target,
4668 GLenum pname,
4669 GLsizei bufSize,
4670 const GLuint *params)
4671{
4672 UNIMPLEMENTED();
4673 return false;
4674}
4675
Geoff Langc1984ed2016-10-07 12:41:00 -04004676bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4677 GLuint sampler,
4678 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004679 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004680 GLsizei *length,
4681 GLfloat *params)
4682{
4683 if (!ValidateRobustEntryPoint(context, bufSize))
4684 {
4685 return false;
4686 }
4687
Brandon Jonesd1049182018-03-28 10:02:20 -07004688 GLsizei numParams = 0;
4689
4690 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004691 {
4692 return false;
4693 }
4694
Brandon Jonesd1049182018-03-28 10:02:20 -07004695 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004696 {
4697 return false;
4698 }
4699
Brandon Jonesd1049182018-03-28 10:02:20 -07004700 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004701 return true;
4702}
4703
Geoff Langc1984ed2016-10-07 12:41:00 -04004704bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4705 GLuint sampler,
4706 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004707 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004708 GLsizei *length,
4709 GLint *params)
4710{
4711 if (!ValidateRobustEntryPoint(context, bufSize))
4712 {
4713 return false;
4714 }
4715
Brandon Jonesd1049182018-03-28 10:02:20 -07004716 GLsizei numParams = 0;
4717
4718 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004719 {
4720 return false;
4721 }
4722
Brandon Jonesd1049182018-03-28 10:02:20 -07004723 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004724 {
4725 return false;
4726 }
4727
Brandon Jonesd1049182018-03-28 10:02:20 -07004728 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004729 return true;
4730}
4731
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004732bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4733 GLuint sampler,
4734 GLenum pname,
4735 GLsizei bufSize,
4736 GLsizei *length,
4737 GLint *params)
4738{
4739 UNIMPLEMENTED();
4740 return false;
4741}
4742
4743bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4744 GLuint sampler,
4745 GLenum pname,
4746 GLsizei bufSize,
4747 GLsizei *length,
4748 GLuint *params)
4749{
4750 UNIMPLEMENTED();
4751 return false;
4752}
4753
Geoff Langc1984ed2016-10-07 12:41:00 -04004754bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4755 GLuint sampler,
4756 GLenum pname,
4757 GLsizei bufSize,
4758 const GLfloat *params)
4759{
4760 if (!ValidateRobustEntryPoint(context, bufSize))
4761 {
4762 return false;
4763 }
4764
Till Rathmannb8543632018-10-02 19:46:14 +02004765 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004766}
4767
Geoff Langc1984ed2016-10-07 12:41:00 -04004768bool ValidateSamplerParameterivRobustANGLE(Context *context,
4769 GLuint sampler,
4770 GLenum pname,
4771 GLsizei bufSize,
4772 const GLint *params)
4773{
4774 if (!ValidateRobustEntryPoint(context, bufSize))
4775 {
4776 return false;
4777 }
4778
Till Rathmannb8543632018-10-02 19:46:14 +02004779 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004780}
4781
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004782bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4783 GLuint sampler,
4784 GLenum pname,
4785 GLsizei bufSize,
4786 const GLint *param)
4787{
4788 UNIMPLEMENTED();
4789 return false;
4790}
4791
4792bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4793 GLuint sampler,
4794 GLenum pname,
4795 GLsizei bufSize,
4796 const GLuint *param)
4797{
4798 UNIMPLEMENTED();
4799 return false;
4800}
4801
Geoff Lang0b031062016-10-13 14:30:04 -04004802bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4803 GLuint index,
4804 GLenum pname,
4805 GLsizei bufSize,
4806 GLsizei *length,
4807 GLfloat *params)
4808{
4809 if (!ValidateRobustEntryPoint(context, bufSize))
4810 {
4811 return false;
4812 }
4813
Brandon Jonesd1049182018-03-28 10:02:20 -07004814 GLsizei writeLength = 0;
4815
4816 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004817 {
4818 return false;
4819 }
4820
Brandon Jonesd1049182018-03-28 10:02:20 -07004821 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004822 {
4823 return false;
4824 }
4825
Brandon Jonesd1049182018-03-28 10:02:20 -07004826 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004827 return true;
4828}
4829
Geoff Lang0b031062016-10-13 14:30:04 -04004830bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4831 GLuint index,
4832 GLenum pname,
4833 GLsizei bufSize,
4834 GLsizei *length,
4835 GLint *params)
4836{
4837 if (!ValidateRobustEntryPoint(context, bufSize))
4838 {
4839 return false;
4840 }
4841
Brandon Jonesd1049182018-03-28 10:02:20 -07004842 GLsizei writeLength = 0;
4843
4844 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004845 {
4846 return false;
4847 }
4848
Brandon Jonesd1049182018-03-28 10:02:20 -07004849 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004850 {
4851 return false;
4852 }
4853
Brandon Jonesd1049182018-03-28 10:02:20 -07004854 SetRobustLengthParam(length, writeLength);
4855
Geoff Lang0b031062016-10-13 14:30:04 -04004856 return true;
4857}
4858
Geoff Lang0b031062016-10-13 14:30:04 -04004859bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4860 GLuint index,
4861 GLenum pname,
4862 GLsizei bufSize,
4863 GLsizei *length,
4864 void **pointer)
4865{
4866 if (!ValidateRobustEntryPoint(context, bufSize))
4867 {
4868 return false;
4869 }
4870
Brandon Jonesd1049182018-03-28 10:02:20 -07004871 GLsizei writeLength = 0;
4872
4873 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004874 {
4875 return false;
4876 }
4877
Brandon Jonesd1049182018-03-28 10:02:20 -07004878 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004879 {
4880 return false;
4881 }
4882
Brandon Jonesd1049182018-03-28 10:02:20 -07004883 SetRobustLengthParam(length, writeLength);
4884
Geoff Lang0b031062016-10-13 14:30:04 -04004885 return true;
4886}
4887
Geoff Lang0b031062016-10-13 14:30:04 -04004888bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4889 GLuint index,
4890 GLenum pname,
4891 GLsizei bufSize,
4892 GLsizei *length,
4893 GLint *params)
4894{
4895 if (!ValidateRobustEntryPoint(context, bufSize))
4896 {
4897 return false;
4898 }
4899
Brandon Jonesd1049182018-03-28 10:02:20 -07004900 GLsizei writeLength = 0;
4901
4902 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004903 {
4904 return false;
4905 }
4906
Brandon Jonesd1049182018-03-28 10:02:20 -07004907 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004908 {
4909 return false;
4910 }
4911
Brandon Jonesd1049182018-03-28 10:02:20 -07004912 SetRobustLengthParam(length, writeLength);
4913
Geoff Lang0b031062016-10-13 14:30:04 -04004914 return true;
4915}
4916
Geoff Lang0b031062016-10-13 14:30:04 -04004917bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
4918 GLuint index,
4919 GLenum pname,
4920 GLsizei bufSize,
4921 GLsizei *length,
4922 GLuint *params)
4923{
4924 if (!ValidateRobustEntryPoint(context, bufSize))
4925 {
4926 return false;
4927 }
4928
Brandon Jonesd1049182018-03-28 10:02:20 -07004929 GLsizei writeLength = 0;
4930
4931 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004932 {
4933 return false;
4934 }
4935
Brandon Jonesd1049182018-03-28 10:02:20 -07004936 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004937 {
4938 return false;
4939 }
4940
Brandon Jonesd1049182018-03-28 10:02:20 -07004941 SetRobustLengthParam(length, writeLength);
4942
Geoff Lang0b031062016-10-13 14:30:04 -04004943 return true;
4944}
4945
Geoff Lang6899b872016-10-14 11:30:13 -04004946bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
4947 GLuint program,
4948 GLuint uniformBlockIndex,
4949 GLenum pname,
4950 GLsizei bufSize,
4951 GLsizei *length,
4952 GLint *params)
4953{
4954 if (!ValidateRobustEntryPoint(context, bufSize))
4955 {
4956 return false;
4957 }
4958
Brandon Jonesd1049182018-03-28 10:02:20 -07004959 GLsizei writeLength = 0;
4960
4961 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
4962 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04004963 {
4964 return false;
4965 }
4966
Brandon Jonesd1049182018-03-28 10:02:20 -07004967 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04004968 {
4969 return false;
4970 }
4971
Brandon Jonesd1049182018-03-28 10:02:20 -07004972 SetRobustLengthParam(length, writeLength);
4973
Geoff Lang6899b872016-10-14 11:30:13 -04004974 return true;
4975}
4976
Brandon Jones416aaf92018-04-10 08:10:16 -07004977bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07004978 GLenum target,
4979 GLenum internalformat,
4980 GLenum pname,
4981 GLsizei bufSize,
4982 GLsizei *length,
4983 GLint *params)
4984{
4985 if (!ValidateRobustEntryPoint(context, bufSize))
4986 {
4987 return false;
4988 }
4989
Brandon Jonesd1049182018-03-28 10:02:20 -07004990 GLsizei numParams = 0;
4991
4992 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4993 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07004994 {
4995 return false;
4996 }
4997
Brandon Jonesd1049182018-03-28 10:02:20 -07004998 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07004999 {
5000 return false;
5001 }
5002
Brandon Jonesd1049182018-03-28 10:02:20 -07005003 SetRobustLengthParam(length, numParams);
5004
Geoff Lang0a9661f2016-10-20 10:59:20 -07005005 return true;
5006}
5007
Jamie Madill5b772312018-03-08 20:28:32 -05005008bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005009 GLuint attribIndex,
5010 GLint size,
5011 GLenum type,
5012 GLboolean pureInteger)
5013{
5014 const Caps &caps = context->getCaps();
5015 if (attribIndex >= caps.maxVertexAttributes)
5016 {
Jamie Madille0472f32018-11-27 16:32:45 -05005017 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005018 return false;
5019 }
5020
5021 if (size < 1 || size > 4)
5022 {
Jamie Madille0472f32018-11-27 16:32:45 -05005023 context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005024 return false;
Shao80957d92017-02-20 21:25:59 +08005025 }
5026
5027 switch (type)
5028 {
5029 case GL_BYTE:
5030 case GL_UNSIGNED_BYTE:
5031 case GL_SHORT:
5032 case GL_UNSIGNED_SHORT:
5033 break;
5034
5035 case GL_INT:
5036 case GL_UNSIGNED_INT:
5037 if (context->getClientMajorVersion() < 3)
5038 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005039 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08005040 return false;
5041 }
5042 break;
5043
5044 case GL_FIXED:
5045 case GL_FLOAT:
5046 if (pureInteger)
5047 {
Jamie Madille0472f32018-11-27 16:32:45 -05005048 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005049 return false;
5050 }
5051 break;
5052
5053 case GL_HALF_FLOAT:
5054 if (context->getClientMajorVersion() < 3)
5055 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005056 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08005057 return false;
5058 }
5059 if (pureInteger)
5060 {
Jamie Madille0472f32018-11-27 16:32:45 -05005061 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005062 return false;
5063 }
5064 break;
5065
5066 case GL_INT_2_10_10_10_REV:
5067 case GL_UNSIGNED_INT_2_10_10_10_REV:
5068 if (context->getClientMajorVersion() < 3)
5069 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005070 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08005071 return false;
5072 }
5073 if (pureInteger)
5074 {
Jamie Madille0472f32018-11-27 16:32:45 -05005075 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005076 return false;
5077 }
5078 if (size != 4)
5079 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005080 context->validationError(GL_INVALID_OPERATION, kInvalidVertexAttribSize2101010);
Shao80957d92017-02-20 21:25:59 +08005081 return false;
5082 }
5083 break;
5084
5085 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005086 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08005087 return false;
5088 }
5089
5090 return true;
5091}
5092
Geoff Lang76e65652017-03-27 14:58:02 -04005093// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5094// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5095// specified clear value and the type of a buffer that is being cleared generates an
5096// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005097bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005098 GLint drawbuffer,
5099 const GLenum *validComponentTypes,
5100 size_t validComponentTypeCount)
5101{
5102 const FramebufferAttachment *attachment =
5103 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5104 if (attachment)
5105 {
5106 GLenum componentType = attachment->getFormat().info->componentType;
5107 const GLenum *end = validComponentTypes + validComponentTypeCount;
5108 if (std::find(validComponentTypes, end, componentType) == end)
5109 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005110 context->validationError(GL_INVALID_OPERATION, kNoDefinedClearConversion);
Geoff Lang76e65652017-03-27 14:58:02 -04005111 return false;
5112 }
5113 }
5114
5115 return true;
5116}
5117
Jamie Madill5b772312018-03-08 20:28:32 -05005118bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005119{
5120 if (!ValidateRobustEntryPoint(context, dataSize))
5121 {
5122 return false;
5123 }
5124
Jamie Madill43da7c42018-08-01 11:34:49 -04005125 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005126 if (pixelUnpackBuffer == nullptr)
5127 {
5128 if (dataSize < imageSize)
5129 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005130 context->validationError(GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
Corentin Wallezb2931602017-04-11 15:58:57 -04005131 }
5132 }
5133 return true;
5134}
5135
Jamie Madill5b772312018-03-08 20:28:32 -05005136bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005137 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005138 GLenum pname,
5139 bool pointerVersion,
5140 GLsizei *numParams)
5141{
5142 if (numParams)
5143 {
5144 *numParams = 0;
5145 }
5146
Corentin Walleze4477002017-12-01 14:39:58 -05005147 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005148 {
Jamie Madille0472f32018-11-27 16:32:45 -05005149 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005150 return false;
5151 }
5152
5153 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5154 if (!buffer)
5155 {
5156 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05005157 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005158 return false;
5159 }
5160
5161 const Extensions &extensions = context->getExtensions();
5162
5163 switch (pname)
5164 {
5165 case GL_BUFFER_USAGE:
5166 case GL_BUFFER_SIZE:
5167 break;
5168
5169 case GL_BUFFER_ACCESS_OES:
5170 if (!extensions.mapBuffer)
5171 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005172 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005173 return false;
5174 }
5175 break;
5176
5177 case GL_BUFFER_MAPPED:
5178 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5179 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5180 !extensions.mapBufferRange)
5181 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005182 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005183 return false;
5184 }
5185 break;
5186
5187 case GL_BUFFER_MAP_POINTER:
5188 if (!pointerVersion)
5189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005190 context->validationError(GL_INVALID_ENUM, kInvalidMapPointerQuery);
Jamie Madillbe849e42017-05-02 15:49:00 -04005191 return false;
5192 }
5193 break;
5194
5195 case GL_BUFFER_ACCESS_FLAGS:
5196 case GL_BUFFER_MAP_OFFSET:
5197 case GL_BUFFER_MAP_LENGTH:
5198 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5199 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005200 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005201 return false;
5202 }
5203 break;
5204
Geoff Lang79b91402018-10-04 15:11:30 -04005205 case GL_MEMORY_SIZE_ANGLE:
5206 if (!context->getExtensions().memorySize)
5207 {
Jamie Madille0472f32018-11-27 16:32:45 -05005208 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005209 return false;
5210 }
5211 break;
5212
Jamie Madillbe849e42017-05-02 15:49:00 -04005213 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005214 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005215 return false;
5216 }
5217
5218 // All buffer parameter queries return one value.
5219 if (numParams)
5220 {
5221 *numParams = 1;
5222 }
5223
5224 return true;
5225}
5226
5227bool ValidateGetRenderbufferParameterivBase(Context *context,
5228 GLenum target,
5229 GLenum pname,
5230 GLsizei *length)
5231{
5232 if (length)
5233 {
5234 *length = 0;
5235 }
5236
5237 if (target != GL_RENDERBUFFER)
5238 {
Jamie Madille0472f32018-11-27 16:32:45 -05005239 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005240 return false;
5241 }
5242
5243 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5244 if (renderbuffer == nullptr)
5245 {
Jamie Madille0472f32018-11-27 16:32:45 -05005246 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005247 return false;
5248 }
5249
5250 switch (pname)
5251 {
5252 case GL_RENDERBUFFER_WIDTH:
5253 case GL_RENDERBUFFER_HEIGHT:
5254 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5255 case GL_RENDERBUFFER_RED_SIZE:
5256 case GL_RENDERBUFFER_GREEN_SIZE:
5257 case GL_RENDERBUFFER_BLUE_SIZE:
5258 case GL_RENDERBUFFER_ALPHA_SIZE:
5259 case GL_RENDERBUFFER_DEPTH_SIZE:
5260 case GL_RENDERBUFFER_STENCIL_SIZE:
5261 break;
5262
5263 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5264 if (!context->getExtensions().framebufferMultisample)
5265 {
Jamie Madille0472f32018-11-27 16:32:45 -05005266 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005267 return false;
5268 }
5269 break;
5270
Geoff Lang79b91402018-10-04 15:11:30 -04005271 case GL_MEMORY_SIZE_ANGLE:
5272 if (!context->getExtensions().memorySize)
5273 {
Jamie Madille0472f32018-11-27 16:32:45 -05005274 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005275 return false;
5276 }
5277 break;
5278
Jamie Madillbe849e42017-05-02 15:49:00 -04005279 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005280 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005281 return false;
5282 }
5283
5284 if (length)
5285 {
5286 *length = 1;
5287 }
5288 return true;
5289}
5290
5291bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5292{
5293 if (length)
5294 {
5295 *length = 0;
5296 }
5297
5298 if (GetValidShader(context, shader) == nullptr)
5299 {
5300 return false;
5301 }
5302
5303 switch (pname)
5304 {
5305 case GL_SHADER_TYPE:
5306 case GL_DELETE_STATUS:
5307 case GL_COMPILE_STATUS:
5308 case GL_INFO_LOG_LENGTH:
5309 case GL_SHADER_SOURCE_LENGTH:
5310 break;
5311
5312 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5313 if (!context->getExtensions().translatedShaderSource)
5314 {
Jamie Madille0472f32018-11-27 16:32:45 -05005315 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005316 return false;
5317 }
5318 break;
5319
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005320 case GL_COMPLETION_STATUS_KHR:
5321 if (!context->getExtensions().parallelShaderCompile)
5322 {
Jamie Madille0472f32018-11-27 16:32:45 -05005323 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005324 return false;
5325 }
5326 break;
5327
Jamie Madillbe849e42017-05-02 15:49:00 -04005328 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005329 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005330 return false;
5331 }
5332
5333 if (length)
5334 {
5335 *length = 1;
5336 }
5337 return true;
5338}
5339
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005340bool ValidateGetTexParameterBase(Context *context,
5341 TextureType target,
5342 GLenum pname,
5343 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005344{
5345 if (length)
5346 {
5347 *length = 0;
5348 }
5349
5350 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5351 {
Jamie Madille0472f32018-11-27 16:32:45 -05005352 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005353 return false;
5354 }
5355
5356 if (context->getTargetTexture(target) == nullptr)
5357 {
5358 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005359 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005360 return false;
5361 }
5362
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005363 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5364 {
Jamie Madille0472f32018-11-27 16:32:45 -05005365 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005366 return false;
5367 }
5368
Jamie Madillbe849e42017-05-02 15:49:00 -04005369 switch (pname)
5370 {
5371 case GL_TEXTURE_MAG_FILTER:
5372 case GL_TEXTURE_MIN_FILTER:
5373 case GL_TEXTURE_WRAP_S:
5374 case GL_TEXTURE_WRAP_T:
5375 break;
5376
5377 case GL_TEXTURE_USAGE_ANGLE:
5378 if (!context->getExtensions().textureUsage)
5379 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005380 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005381 return false;
5382 }
5383 break;
5384
5385 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005386 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005387 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005388 return false;
5389 }
5390 break;
5391
5392 case GL_TEXTURE_IMMUTABLE_FORMAT:
5393 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5394 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005395 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005396 return false;
5397 }
5398 break;
5399
5400 case GL_TEXTURE_WRAP_R:
5401 case GL_TEXTURE_IMMUTABLE_LEVELS:
5402 case GL_TEXTURE_SWIZZLE_R:
5403 case GL_TEXTURE_SWIZZLE_G:
5404 case GL_TEXTURE_SWIZZLE_B:
5405 case GL_TEXTURE_SWIZZLE_A:
5406 case GL_TEXTURE_BASE_LEVEL:
5407 case GL_TEXTURE_MAX_LEVEL:
5408 case GL_TEXTURE_MIN_LOD:
5409 case GL_TEXTURE_MAX_LOD:
5410 case GL_TEXTURE_COMPARE_MODE:
5411 case GL_TEXTURE_COMPARE_FUNC:
5412 if (context->getClientMajorVersion() < 3)
5413 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005414 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Jamie Madillbe849e42017-05-02 15:49:00 -04005415 return false;
5416 }
5417 break;
5418
5419 case GL_TEXTURE_SRGB_DECODE_EXT:
5420 if (!context->getExtensions().textureSRGBDecode)
5421 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005422 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005423 return false;
5424 }
5425 break;
5426
Yunchao Hebacaa712018-01-30 14:01:39 +08005427 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5428 if (context->getClientVersion() < Version(3, 1))
5429 {
Jamie Madille0472f32018-11-27 16:32:45 -05005430 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005431 return false;
5432 }
5433 break;
5434
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005435 case GL_GENERATE_MIPMAP:
5436 case GL_TEXTURE_CROP_RECT_OES:
5437 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5438 // after GL_OES_draw_texture functionality implemented
5439 if (context->getClientMajorVersion() > 1)
5440 {
Jamie Madille0472f32018-11-27 16:32:45 -05005441 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005442 return false;
5443 }
5444 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005445
5446 case GL_MEMORY_SIZE_ANGLE:
5447 if (!context->getExtensions().memorySize)
5448 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005449 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang79b91402018-10-04 15:11:30 -04005450 return false;
5451 }
5452 break;
5453
Till Rathmannb8543632018-10-02 19:46:14 +02005454 case GL_TEXTURE_BORDER_COLOR:
5455 if (!context->getExtensions().textureBorderClamp)
5456 {
Jamie Madille0472f32018-11-27 16:32:45 -05005457 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005458 return false;
5459 }
5460 break;
5461
Jamie Madillbe849e42017-05-02 15:49:00 -04005462 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005463 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005464 return false;
5465 }
5466
5467 if (length)
5468 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005469 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005470 }
5471 return true;
5472}
5473
5474bool ValidateGetVertexAttribBase(Context *context,
5475 GLuint index,
5476 GLenum pname,
5477 GLsizei *length,
5478 bool pointer,
5479 bool pureIntegerEntryPoint)
5480{
5481 if (length)
5482 {
5483 *length = 0;
5484 }
5485
5486 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5487 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005488 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005489 return false;
5490 }
5491
5492 if (index >= context->getCaps().maxVertexAttributes)
5493 {
Jamie Madille0472f32018-11-27 16:32:45 -05005494 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005495 return false;
5496 }
5497
5498 if (pointer)
5499 {
5500 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5501 {
Jamie Madille0472f32018-11-27 16:32:45 -05005502 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005503 return false;
5504 }
5505 }
5506 else
5507 {
5508 switch (pname)
5509 {
5510 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5511 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5512 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5513 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5514 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5515 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5516 case GL_CURRENT_VERTEX_ATTRIB:
5517 break;
5518
5519 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5520 static_assert(
5521 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5522 "ANGLE extension enums not equal to GL enums.");
5523 if (context->getClientMajorVersion() < 3 &&
5524 !context->getExtensions().instancedArrays)
5525 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005526 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005527 return false;
5528 }
5529 break;
5530
5531 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5532 if (context->getClientMajorVersion() < 3)
5533 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005534 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005535 return false;
5536 }
5537 break;
5538
5539 case GL_VERTEX_ATTRIB_BINDING:
5540 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5541 if (context->getClientVersion() < ES_3_1)
5542 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005543 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005544 return false;
5545 }
5546 break;
5547
5548 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005549 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005550 return false;
5551 }
5552 }
5553
5554 if (length)
5555 {
5556 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5557 {
5558 *length = 4;
5559 }
5560 else
5561 {
5562 *length = 1;
5563 }
5564 }
5565
5566 return true;
5567}
5568
Jamie Madill4928b7c2017-06-20 12:57:39 -04005569bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005570 GLint x,
5571 GLint y,
5572 GLsizei width,
5573 GLsizei height,
5574 GLenum format,
5575 GLenum type,
5576 GLsizei bufSize,
5577 GLsizei *length,
5578 GLsizei *columns,
5579 GLsizei *rows,
5580 void *pixels)
5581{
5582 if (length != nullptr)
5583 {
5584 *length = 0;
5585 }
5586 if (rows != nullptr)
5587 {
5588 *rows = 0;
5589 }
5590 if (columns != nullptr)
5591 {
5592 *columns = 0;
5593 }
5594
5595 if (width < 0 || height < 0)
5596 {
Jamie Madille0472f32018-11-27 16:32:45 -05005597 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005598 return false;
5599 }
5600
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005601 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005602
Jamie Madill427064d2018-04-13 16:20:34 -04005603 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005604 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005605 return false;
5606 }
5607
Jamie Madille98b1b52018-03-08 09:47:23 -05005608 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005609 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005610 return false;
5611 }
5612
Jamie Madill690c8eb2018-03-12 15:20:03 -04005613 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005614 ASSERT(framebuffer);
5615
5616 if (framebuffer->getReadBufferState() == GL_NONE)
5617 {
Jamie Madille0472f32018-11-27 16:32:45 -05005618 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005619 return false;
5620 }
5621
5622 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5623 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5624 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5625 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5626 // situation is an application error that would lead to a crash in ANGLE.
5627 if (readBuffer == nullptr)
5628 {
Jamie Madille0472f32018-11-27 16:32:45 -05005629 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005630 return false;
5631 }
5632
Martin Radev28031682017-07-28 14:47:56 +03005633 // ANGLE_multiview, Revision 1:
5634 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005635 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5636 // in the current read framebuffer is more than one.
5637 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005638 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005639 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
Martin Radev28031682017-07-28 14:47:56 +03005640 return false;
5641 }
5642
Geoff Lang280ba992017-04-18 16:30:58 -04005643 if (context->getExtensions().webglCompatibility)
5644 {
5645 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5646 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5647 // and type before validating the combination of format and type. However, the
5648 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5649 // verifies that GL_INVALID_OPERATION is generated.
5650 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5651 // dEQP/WebGL.
5652 if (!ValidReadPixelsFormatEnum(context, format))
5653 {
Jamie Madille0472f32018-11-27 16:32:45 -05005654 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005655 return false;
5656 }
5657
5658 if (!ValidReadPixelsTypeEnum(context, type))
5659 {
Jamie Madille0472f32018-11-27 16:32:45 -05005660 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005661 return false;
5662 }
5663 }
5664
Jamie Madill690c8eb2018-03-12 15:20:03 -04005665 GLenum currentFormat = GL_NONE;
5666 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5667
5668 GLenum currentType = GL_NONE;
5669 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5670
Jamie Madillbe849e42017-05-02 15:49:00 -04005671 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5672
5673 bool validFormatTypeCombination =
5674 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5675
5676 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5677 {
Jamie Madille0472f32018-11-27 16:32:45 -05005678 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005679 return false;
5680 }
5681
5682 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005683 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005684 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5685 {
5686 // ...the buffer object's data store is currently mapped.
Jamie Madillc3e37312018-11-30 15:25:39 -05005687 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madillbe849e42017-05-02 15:49:00 -04005688 return false;
5689 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005690 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5691 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5692 {
Jamie Madille0472f32018-11-27 16:32:45 -05005693 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005694 return false;
5695 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005696
5697 // .. the data would be packed to the buffer object such that the memory writes required
5698 // would exceed the data store size.
5699 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005700 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005701 const auto &pack = context->getGLState().getPackState();
5702
Jamie Madillca2ff382018-07-11 09:01:17 -04005703 GLuint endByte = 0;
5704 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005705 {
Jamie Madille0472f32018-11-27 16:32:45 -05005706 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005707 return false;
5708 }
5709
Jamie Madillbe849e42017-05-02 15:49:00 -04005710 if (bufSize >= 0)
5711 {
5712 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5713 {
Jamie Madille0472f32018-11-27 16:32:45 -05005714 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005715 return false;
5716 }
5717 }
5718
5719 if (pixelPackBuffer != nullptr)
5720 {
5721 CheckedNumeric<size_t> checkedEndByte(endByte);
5722 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5723 checkedEndByte += checkedOffset;
5724
5725 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5726 {
5727 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005728 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005729 return false;
5730 }
5731 }
5732
5733 if (pixelPackBuffer == nullptr && length != nullptr)
5734 {
5735 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5736 {
Jamie Madille0472f32018-11-27 16:32:45 -05005737 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005738 return false;
5739 }
5740
5741 *length = static_cast<GLsizei>(endByte);
5742 }
5743
Geoff Langa953b522018-02-21 16:56:23 -05005744 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005745 angle::CheckedNumeric<int> clippedExtent(length);
5746 if (start < 0)
5747 {
5748 // "subtract" the area that is less than 0
5749 clippedExtent += start;
5750 }
5751
Geoff Langa953b522018-02-21 16:56:23 -05005752 angle::CheckedNumeric<int> readExtent = start;
5753 readExtent += length;
5754 if (!readExtent.IsValid())
5755 {
5756 return false;
5757 }
5758
5759 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005760 {
5761 // Subtract the region to the right of the read buffer
5762 clippedExtent -= (readExtent - bufferSize);
5763 }
5764
5765 if (!clippedExtent.IsValid())
5766 {
Geoff Langa953b522018-02-21 16:56:23 -05005767 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005768 }
5769
Geoff Langa953b522018-02-21 16:56:23 -05005770 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5771 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005772 };
5773
Geoff Langa953b522018-02-21 16:56:23 -05005774 GLsizei writtenColumns = 0;
5775 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5776 {
Jamie Madille0472f32018-11-27 16:32:45 -05005777 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005778 return false;
5779 }
5780
5781 GLsizei writtenRows = 0;
5782 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5783 {
Jamie Madille0472f32018-11-27 16:32:45 -05005784 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005785 return false;
5786 }
5787
Jamie Madillbe849e42017-05-02 15:49:00 -04005788 if (columns != nullptr)
5789 {
Geoff Langa953b522018-02-21 16:56:23 -05005790 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005791 }
5792
5793 if (rows != nullptr)
5794 {
Geoff Langa953b522018-02-21 16:56:23 -05005795 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005796 }
5797
5798 return true;
5799}
5800
5801template <typename ParamType>
5802bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005803 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005804 GLenum pname,
5805 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005806 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005807 const ParamType *params)
5808{
5809 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5810 {
Jamie Madille0472f32018-11-27 16:32:45 -05005811 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005812 return false;
5813 }
5814
5815 if (context->getTargetTexture(target) == nullptr)
5816 {
5817 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005818 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005819 return false;
5820 }
5821
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005822 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005823 if (bufSize >= 0 && bufSize < minBufSize)
5824 {
Jamie Madille0472f32018-11-27 16:32:45 -05005825 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005826 return false;
5827 }
5828
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005829 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5830 {
Jamie Madille0472f32018-11-27 16:32:45 -05005831 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005832 return false;
5833 }
5834
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 switch (pname)
5836 {
5837 case GL_TEXTURE_WRAP_R:
5838 case GL_TEXTURE_SWIZZLE_R:
5839 case GL_TEXTURE_SWIZZLE_G:
5840 case GL_TEXTURE_SWIZZLE_B:
5841 case GL_TEXTURE_SWIZZLE_A:
5842 case GL_TEXTURE_BASE_LEVEL:
5843 case GL_TEXTURE_MAX_LEVEL:
5844 case GL_TEXTURE_COMPARE_MODE:
5845 case GL_TEXTURE_COMPARE_FUNC:
5846 case GL_TEXTURE_MIN_LOD:
5847 case GL_TEXTURE_MAX_LOD:
5848 if (context->getClientMajorVersion() < 3)
5849 {
Jamie Madille0472f32018-11-27 16:32:45 -05005850 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005851 return false;
5852 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005853 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005854 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005855 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005856 return false;
5857 }
5858 break;
5859
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005860 case GL_GENERATE_MIPMAP:
5861 case GL_TEXTURE_CROP_RECT_OES:
5862 if (context->getClientMajorVersion() > 1)
5863 {
Jamie Madille0472f32018-11-27 16:32:45 -05005864 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005865 return false;
5866 }
5867 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005868 default:
5869 break;
5870 }
5871
Olli Etuahod310a432018-08-24 15:40:23 +03005872 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005873 {
5874 switch (pname)
5875 {
5876 case GL_TEXTURE_MIN_FILTER:
5877 case GL_TEXTURE_MAG_FILTER:
5878 case GL_TEXTURE_WRAP_S:
5879 case GL_TEXTURE_WRAP_T:
5880 case GL_TEXTURE_WRAP_R:
5881 case GL_TEXTURE_MIN_LOD:
5882 case GL_TEXTURE_MAX_LOD:
5883 case GL_TEXTURE_COMPARE_MODE:
5884 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005885 case GL_TEXTURE_BORDER_COLOR:
Jamie Madillc3e37312018-11-30 15:25:39 -05005886 context->validationError(GL_INVALID_ENUM, kInvalidPname);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005887 return false;
5888 }
5889 }
5890
Jamie Madillbe849e42017-05-02 15:49:00 -04005891 switch (pname)
5892 {
5893 case GL_TEXTURE_WRAP_S:
5894 case GL_TEXTURE_WRAP_T:
5895 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005896 {
5897 bool restrictedWrapModes =
5898 target == TextureType::External || target == TextureType::Rectangle;
5899 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04005900 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005901 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005902 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005903 }
5904 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005905
5906 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005907 {
5908 bool restrictedMinFilter =
5909 target == TextureType::External || target == TextureType::Rectangle;
5910 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04005911 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005912 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005913 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005914 }
5915 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005916
5917 case GL_TEXTURE_MAG_FILTER:
5918 if (!ValidateTextureMagFilterValue(context, params))
5919 {
5920 return false;
5921 }
5922 break;
5923
5924 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04005925 if (!context->getExtensions().textureUsage)
5926 {
Jamie Madille0472f32018-11-27 16:32:45 -05005927 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04005928 return false;
5929 }
5930
Jamie Madillbe849e42017-05-02 15:49:00 -04005931 switch (ConvertToGLenum(params[0]))
5932 {
5933 case GL_NONE:
5934 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
5935 break;
5936
5937 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005938 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005939 return false;
5940 }
5941 break;
5942
5943 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005944 {
5945 GLfloat paramValue = static_cast<GLfloat>(params[0]);
5946 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04005947 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005948 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005949 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005950 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
5951 }
5952 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005953
5954 case GL_TEXTURE_MIN_LOD:
5955 case GL_TEXTURE_MAX_LOD:
5956 // any value is permissible
5957 break;
5958
5959 case GL_TEXTURE_COMPARE_MODE:
5960 if (!ValidateTextureCompareModeValue(context, params))
5961 {
5962 return false;
5963 }
5964 break;
5965
5966 case GL_TEXTURE_COMPARE_FUNC:
5967 if (!ValidateTextureCompareFuncValue(context, params))
5968 {
5969 return false;
5970 }
5971 break;
5972
5973 case GL_TEXTURE_SWIZZLE_R:
5974 case GL_TEXTURE_SWIZZLE_G:
5975 case GL_TEXTURE_SWIZZLE_B:
5976 case GL_TEXTURE_SWIZZLE_A:
5977 switch (ConvertToGLenum(params[0]))
5978 {
5979 case GL_RED:
5980 case GL_GREEN:
5981 case GL_BLUE:
5982 case GL_ALPHA:
5983 case GL_ZERO:
5984 case GL_ONE:
5985 break;
5986
5987 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005988 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005989 return false;
5990 }
5991 break;
5992
5993 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005994 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005995 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005996 context->validationError(GL_INVALID_VALUE, kBaseLevelNegative);
Jamie Madillbe849e42017-05-02 15:49:00 -04005997 return false;
5998 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005999 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006000 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006001 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 return false;
6003 }
Olli Etuahod310a432018-08-24 15:40:23 +03006004 if ((target == TextureType::_2DMultisample ||
6005 target == TextureType::_2DMultisampleArray) &&
6006 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006007 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006008 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
JiangYizhou4cff8d62017-07-06 14:54:09 +08006009 return false;
6010 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006011 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006012 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006013 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006014 return false;
6015 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 break;
6017
6018 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006019 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 {
Jamie Madille0472f32018-11-27 16:32:45 -05006021 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 return false;
6023 }
6024 break;
6025
6026 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6027 if (context->getClientVersion() < Version(3, 1))
6028 {
Jamie Madille0472f32018-11-27 16:32:45 -05006029 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006030 return false;
6031 }
6032 switch (ConvertToGLenum(params[0]))
6033 {
6034 case GL_DEPTH_COMPONENT:
6035 case GL_STENCIL_INDEX:
6036 break;
6037
6038 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006039 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 return false;
6041 }
6042 break;
6043
6044 case GL_TEXTURE_SRGB_DECODE_EXT:
6045 if (!ValidateTextureSRGBDecodeValue(context, params))
6046 {
6047 return false;
6048 }
6049 break;
6050
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006051 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006052 if (context->getClientMajorVersion() > 1)
6053 {
Jamie Madille0472f32018-11-27 16:32:45 -05006054 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006055 return false;
6056 }
6057 break;
Till Rathmannb8543632018-10-02 19:46:14 +02006058
6059 case GL_TEXTURE_CROP_RECT_OES:
6060 if (context->getClientMajorVersion() > 1)
6061 {
Jamie Madille0472f32018-11-27 16:32:45 -05006062 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02006063 return false;
6064 }
6065 if (!vectorParams)
6066 {
Jamie Madille0472f32018-11-27 16:32:45 -05006067 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006068 return false;
6069 }
6070 break;
6071
6072 case GL_TEXTURE_BORDER_COLOR:
6073 if (!context->getExtensions().textureBorderClamp)
6074 {
Jamie Madille0472f32018-11-27 16:32:45 -05006075 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006076 return false;
6077 }
6078 if (!vectorParams)
6079 {
Jamie Madille0472f32018-11-27 16:32:45 -05006080 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006081 return false;
6082 }
6083 break;
6084
Jamie Madillbe849e42017-05-02 15:49:00 -04006085 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006086 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006087 return false;
6088 }
6089
6090 return true;
6091}
6092
Till Rathmannb8543632018-10-02 19:46:14 +02006093template bool ValidateTexParameterBase(Context *,
6094 TextureType,
6095 GLenum,
6096 GLsizei,
6097 bool,
6098 const GLfloat *);
6099template bool ValidateTexParameterBase(Context *,
6100 TextureType,
6101 GLenum,
6102 GLsizei,
6103 bool,
6104 const GLint *);
6105template bool ValidateTexParameterBase(Context *,
6106 TextureType,
6107 GLenum,
6108 GLsizei,
6109 bool,
6110 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006111
Jamie Madill5b772312018-03-08 20:28:32 -05006112bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006113{
6114 if (index >= MAX_VERTEX_ATTRIBS)
6115 {
Jamie Madille0472f32018-11-27 16:32:45 -05006116 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04006117 return false;
6118 }
6119
6120 return true;
6121}
6122
6123bool ValidateGetActiveUniformBlockivBase(Context *context,
6124 GLuint program,
6125 GLuint uniformBlockIndex,
6126 GLenum pname,
6127 GLsizei *length)
6128{
6129 if (length)
6130 {
6131 *length = 0;
6132 }
6133
6134 if (context->getClientMajorVersion() < 3)
6135 {
Jamie Madille0472f32018-11-27 16:32:45 -05006136 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04006137 return false;
6138 }
6139
6140 Program *programObject = GetValidProgram(context, program);
6141 if (!programObject)
6142 {
6143 return false;
6144 }
6145
6146 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6147 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006148 context->validationError(GL_INVALID_VALUE, kIndexExceedsActiveUniformBlockCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04006149 return false;
6150 }
6151
6152 switch (pname)
6153 {
6154 case GL_UNIFORM_BLOCK_BINDING:
6155 case GL_UNIFORM_BLOCK_DATA_SIZE:
6156 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6157 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6158 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6159 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6160 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6161 break;
6162
6163 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006164 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04006165 return false;
6166 }
6167
6168 if (length)
6169 {
6170 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6171 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006172 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006173 programObject->getUniformBlockByIndex(uniformBlockIndex);
6174 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6175 }
6176 else
6177 {
6178 *length = 1;
6179 }
6180 }
6181
6182 return true;
6183}
6184
Jamie Madill9696d072017-08-26 23:19:57 -04006185template <typename ParamType>
6186bool ValidateSamplerParameterBase(Context *context,
6187 GLuint sampler,
6188 GLenum pname,
6189 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02006190 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04006191 ParamType *params)
6192{
6193 if (context->getClientMajorVersion() < 3)
6194 {
Jamie Madille0472f32018-11-27 16:32:45 -05006195 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006196 return false;
6197 }
6198
6199 if (!context->isSampler(sampler))
6200 {
Jamie Madille0472f32018-11-27 16:32:45 -05006201 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006202 return false;
6203 }
6204
Till Rathmannb8543632018-10-02 19:46:14 +02006205 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006206 if (bufSize >= 0 && bufSize < minBufSize)
6207 {
Jamie Madille0472f32018-11-27 16:32:45 -05006208 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006209 return false;
6210 }
6211
6212 switch (pname)
6213 {
6214 case GL_TEXTURE_WRAP_S:
6215 case GL_TEXTURE_WRAP_T:
6216 case GL_TEXTURE_WRAP_R:
6217 if (!ValidateTextureWrapModeValue(context, params, false))
6218 {
6219 return false;
6220 }
6221 break;
6222
6223 case GL_TEXTURE_MIN_FILTER:
6224 if (!ValidateTextureMinFilterValue(context, params, false))
6225 {
6226 return false;
6227 }
6228 break;
6229
6230 case GL_TEXTURE_MAG_FILTER:
6231 if (!ValidateTextureMagFilterValue(context, params))
6232 {
6233 return false;
6234 }
6235 break;
6236
6237 case GL_TEXTURE_MIN_LOD:
6238 case GL_TEXTURE_MAX_LOD:
6239 // any value is permissible
6240 break;
6241
6242 case GL_TEXTURE_COMPARE_MODE:
6243 if (!ValidateTextureCompareModeValue(context, params))
6244 {
6245 return false;
6246 }
6247 break;
6248
6249 case GL_TEXTURE_COMPARE_FUNC:
6250 if (!ValidateTextureCompareFuncValue(context, params))
6251 {
6252 return false;
6253 }
6254 break;
6255
6256 case GL_TEXTURE_SRGB_DECODE_EXT:
6257 if (!ValidateTextureSRGBDecodeValue(context, params))
6258 {
6259 return false;
6260 }
6261 break;
6262
Luc Ferron1b1a8642018-01-23 15:12:01 -05006263 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6264 {
6265 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6266 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6267 {
6268 return false;
6269 }
6270 }
6271 break;
6272
Till Rathmannb8543632018-10-02 19:46:14 +02006273 case GL_TEXTURE_BORDER_COLOR:
6274 if (!context->getExtensions().textureBorderClamp)
6275 {
Jamie Madille0472f32018-11-27 16:32:45 -05006276 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006277 return false;
6278 }
6279 if (!vectorParams)
6280 {
Jamie Madille0472f32018-11-27 16:32:45 -05006281 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006282 return false;
6283 }
6284 break;
6285
Jamie Madill9696d072017-08-26 23:19:57 -04006286 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006287 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006288 return false;
6289 }
6290
6291 return true;
6292}
6293
Till Rathmannb8543632018-10-02 19:46:14 +02006294template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6295template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6296template bool ValidateSamplerParameterBase(Context *,
6297 GLuint,
6298 GLenum,
6299 GLsizei,
6300 bool,
6301 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006302
6303bool ValidateGetSamplerParameterBase(Context *context,
6304 GLuint sampler,
6305 GLenum pname,
6306 GLsizei *length)
6307{
6308 if (length)
6309 {
6310 *length = 0;
6311 }
6312
6313 if (context->getClientMajorVersion() < 3)
6314 {
Jamie Madille0472f32018-11-27 16:32:45 -05006315 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006316 return false;
6317 }
6318
6319 if (!context->isSampler(sampler))
6320 {
Jamie Madille0472f32018-11-27 16:32:45 -05006321 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006322 return false;
6323 }
6324
6325 switch (pname)
6326 {
6327 case GL_TEXTURE_WRAP_S:
6328 case GL_TEXTURE_WRAP_T:
6329 case GL_TEXTURE_WRAP_R:
6330 case GL_TEXTURE_MIN_FILTER:
6331 case GL_TEXTURE_MAG_FILTER:
6332 case GL_TEXTURE_MIN_LOD:
6333 case GL_TEXTURE_MAX_LOD:
6334 case GL_TEXTURE_COMPARE_MODE:
6335 case GL_TEXTURE_COMPARE_FUNC:
6336 break;
6337
Luc Ferron1b1a8642018-01-23 15:12:01 -05006338 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6339 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6340 {
6341 return false;
6342 }
6343 break;
6344
Jamie Madill9696d072017-08-26 23:19:57 -04006345 case GL_TEXTURE_SRGB_DECODE_EXT:
6346 if (!context->getExtensions().textureSRGBDecode)
6347 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006348 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006349 return false;
6350 }
6351 break;
6352
Till Rathmannb8543632018-10-02 19:46:14 +02006353 case GL_TEXTURE_BORDER_COLOR:
6354 if (!context->getExtensions().textureBorderClamp)
6355 {
Jamie Madille0472f32018-11-27 16:32:45 -05006356 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006357 return false;
6358 }
6359 break;
6360
Jamie Madill9696d072017-08-26 23:19:57 -04006361 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006362 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006363 return false;
6364 }
6365
6366 if (length)
6367 {
Till Rathmannb8543632018-10-02 19:46:14 +02006368 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006369 }
6370 return true;
6371}
6372
6373bool ValidateGetInternalFormativBase(Context *context,
6374 GLenum target,
6375 GLenum internalformat,
6376 GLenum pname,
6377 GLsizei bufSize,
6378 GLsizei *numParams)
6379{
6380 if (numParams)
6381 {
6382 *numParams = 0;
6383 }
6384
6385 if (context->getClientMajorVersion() < 3)
6386 {
Jamie Madille0472f32018-11-27 16:32:45 -05006387 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006388 return false;
6389 }
6390
6391 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006392 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006393 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006394 context->validationError(GL_INVALID_ENUM, kFormatNotRenderable);
Jamie Madill9696d072017-08-26 23:19:57 -04006395 return false;
6396 }
6397
6398 switch (target)
6399 {
6400 case GL_RENDERBUFFER:
6401 break;
6402
6403 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006404 if (context->getClientVersion() < ES_3_1 &&
6405 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006406 {
Jamie Madill610640f2018-11-21 17:28:41 -05006407 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006408 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006409 return false;
6410 }
6411 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006412 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6413 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006414 {
Jamie Madille0472f32018-11-27 16:32:45 -05006415 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006416 return false;
6417 }
6418 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006419 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006420 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006421 return false;
6422 }
6423
6424 if (bufSize < 0)
6425 {
Jamie Madille0472f32018-11-27 16:32:45 -05006426 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006427 return false;
6428 }
6429
6430 GLsizei maxWriteParams = 0;
6431 switch (pname)
6432 {
6433 case GL_NUM_SAMPLE_COUNTS:
6434 maxWriteParams = 1;
6435 break;
6436
6437 case GL_SAMPLES:
6438 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6439 break;
6440
6441 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006442 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006443 return false;
6444 }
6445
6446 if (numParams)
6447 {
6448 // glGetInternalFormativ will not overflow bufSize
6449 *numParams = std::min(bufSize, maxWriteParams);
6450 }
6451
6452 return true;
6453}
6454
Jamie Madille98b1b52018-03-08 09:47:23 -05006455bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6456{
Jamie Madill427064d2018-04-13 16:20:34 -04006457 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006458 {
Jamie Madille0472f32018-11-27 16:32:45 -05006459 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006460 return false;
6461 }
6462 return true;
6463}
6464
Lingfeng Yang038dd532018-03-29 17:31:52 -07006465bool ValidateMultitextureUnit(Context *context, GLenum texture)
6466{
6467 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6468 {
Jamie Madille0472f32018-11-27 16:32:45 -05006469 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006470 return false;
6471 }
6472 return true;
6473}
6474
Olli Etuahod310a432018-08-24 15:40:23 +03006475bool ValidateTexStorageMultisample(Context *context,
6476 TextureType target,
6477 GLsizei samples,
6478 GLint internalFormat,
6479 GLsizei width,
6480 GLsizei height)
6481{
6482 const Caps &caps = context->getCaps();
6483 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6484 static_cast<GLuint>(height) > caps.max2DTextureSize)
6485 {
Jamie Madille0472f32018-11-27 16:32:45 -05006486 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006487 return false;
6488 }
6489
6490 if (samples == 0)
6491 {
Jamie Madille0472f32018-11-27 16:32:45 -05006492 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006493 return false;
6494 }
6495
6496 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6497 if (!formatCaps.textureAttachment)
6498 {
Jamie Madille0472f32018-11-27 16:32:45 -05006499 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006500 return false;
6501 }
6502
6503 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6504 // is one of the unsized base internalformats listed in table 8.11.
6505 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6506 if (formatInfo.internalFormat == GL_NONE)
6507 {
Jamie Madille0472f32018-11-27 16:32:45 -05006508 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006509 return false;
6510 }
6511
6512 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6513 {
Jamie Madille0472f32018-11-27 16:32:45 -05006514 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006515 return false;
6516 }
6517
6518 Texture *texture = context->getTargetTexture(target);
6519 if (!texture || texture->id() == 0)
6520 {
Jamie Madille0472f32018-11-27 16:32:45 -05006521 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006522 return false;
6523 }
6524
6525 if (texture->getImmutableFormat())
6526 {
Jamie Madille0472f32018-11-27 16:32:45 -05006527 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006528 return false;
6529 }
6530 return true;
6531}
6532
Yizhou Jiang7818a852018-09-06 15:02:04 +08006533bool ValidateTexStorage2DMultisampleBase(Context *context,
6534 TextureType target,
6535 GLsizei samples,
6536 GLint internalFormat,
6537 GLsizei width,
6538 GLsizei height)
6539{
6540 if (target != TextureType::_2DMultisample)
6541 {
Jamie Madille0472f32018-11-27 16:32:45 -05006542 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006543 return false;
6544 }
6545
6546 if (width < 1 || height < 1)
6547 {
Jamie Madille0472f32018-11-27 16:32:45 -05006548 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006549 return false;
6550 }
6551
6552 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6553}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006554
6555bool ValidateGetTexLevelParameterBase(Context *context,
6556 TextureTarget target,
6557 GLint level,
6558 GLenum pname,
6559 GLsizei *length)
6560{
6561
6562 if (length)
6563 {
6564 *length = 0;
6565 }
6566
6567 TextureType type = TextureTargetToType(target);
6568
6569 if (!ValidTexLevelDestinationTarget(context, type))
6570 {
Jamie Madille0472f32018-11-27 16:32:45 -05006571 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006572 return false;
6573 }
6574
6575 if (context->getTargetTexture(type) == nullptr)
6576 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006577 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006578 return false;
6579 }
6580
6581 if (!ValidMipLevel(context, type, level))
6582 {
Jamie Madille0472f32018-11-27 16:32:45 -05006583 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006584 return false;
6585 }
6586
6587 switch (pname)
6588 {
6589 case GL_TEXTURE_RED_TYPE:
6590 case GL_TEXTURE_GREEN_TYPE:
6591 case GL_TEXTURE_BLUE_TYPE:
6592 case GL_TEXTURE_ALPHA_TYPE:
6593 case GL_TEXTURE_DEPTH_TYPE:
6594 break;
6595 case GL_TEXTURE_RED_SIZE:
6596 case GL_TEXTURE_GREEN_SIZE:
6597 case GL_TEXTURE_BLUE_SIZE:
6598 case GL_TEXTURE_ALPHA_SIZE:
6599 case GL_TEXTURE_DEPTH_SIZE:
6600 case GL_TEXTURE_STENCIL_SIZE:
6601 case GL_TEXTURE_SHARED_SIZE:
6602 break;
6603 case GL_TEXTURE_INTERNAL_FORMAT:
6604 case GL_TEXTURE_WIDTH:
6605 case GL_TEXTURE_HEIGHT:
6606 case GL_TEXTURE_DEPTH:
6607 break;
6608 case GL_TEXTURE_SAMPLES:
6609 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6610 break;
6611 case GL_TEXTURE_COMPRESSED:
6612 break;
6613 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006614 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006615 return false;
6616 }
6617
6618 if (length)
6619 {
6620 *length = 1;
6621 }
6622 return true;
6623}
Yizhou Jiang7310da32018-11-05 14:40:01 +08006624
6625bool ValidateGetMultisamplefvBase(Context *context, GLenum pname, GLuint index, GLfloat *val)
6626{
6627 if (pname != GL_SAMPLE_POSITION)
6628 {
6629 context->validationError(GL_INVALID_ENUM, kInvalidPname);
6630 return false;
6631 }
6632
6633 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
6634 GLint samples = framebuffer->getSamples(context);
6635
6636 if (index >= static_cast<GLuint>(samples))
6637 {
6638 context->validationError(GL_INVALID_VALUE, kIndexExceedsSamples);
6639 return false;
6640 }
6641
6642 return true;
6643}
6644
6645bool ValidateSampleMaskiBase(Context *context, GLuint maskNumber, GLbitfield mask)
6646{
6647 if (maskNumber >= context->getCaps().maxSampleMaskWords)
6648 {
6649 context->validationError(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
6650 return false;
6651 }
6652
6653 return true;
6654}
Jamie Madillc29968b2016-01-20 11:17:23 -05006655} // namespace gl