blob: 8a8e47121ecce71255eae7e0b0181a60de3eb841 [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"
James Darpinian30b604d2018-03-12 17:26:57 -070021#include "libANGLE/angletypes.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040022#include "libANGLE/formatutils.h"
jchen10a99ed552017-09-22 08:10:32 +080023#include "libANGLE/queryconversions.h"
Lingfeng Yangf97641c2018-06-21 19:22:45 -070024#include "libANGLE/queryutils.h"
Jamie Madill778bf092018-11-14 09:54:36 -050025#include "libANGLE/validationES2_autogen.h"
26#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040027
28#include "common/mathutil.h"
29#include "common/utilities.h"
30
Jamie Madille2e406c2016-06-02 13:04:10 -040031using namespace angle;
32
Geoff Lange8ebe7f2013-08-05 15:03:13 -040033namespace gl
34{
Jamie Madille0472f32018-11-27 16:32:45 -050035using namespace err;
36
Jamie Madill1ca74672015-07-21 15:14:11 -040037namespace
38{
Luc Ferron9dbaeba2018-02-01 07:26:59 -050039bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
40{
41 // List of compressed format that require that the texture size is smaller than or a multiple of
42 // the compressed block size.
43 switch (internalFormat)
44 {
45 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
46 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
47 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
48 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
49 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
50 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
51 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
52 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
53 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
54 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
55 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
56 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
57 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
58 case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
59 case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +030060 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
61 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
62 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
63 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Luc Ferron9dbaeba2018-02-01 07:26:59 -050064 return true;
jchen10a99ed552017-09-22 08:10:32 +080065
Luc Ferron9dbaeba2018-02-01 07:26:59 -050066 default:
67 return false;
68 }
69}
70bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
71{
72 // Compressed sub textures have additional formats that requires exact size.
73 // ES 3.1, Section 8.7, Page 171
74 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
75 IsETC2EACFormat(internalFormat);
76}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030077
78bool DifferenceCanOverflow(GLint a, GLint b)
79{
80 CheckedNumeric<GLint> checkedA(a);
81 checkedA -= b;
82 // Use negation to make sure that the difference can't overflow regardless of the order.
83 checkedA = -checkedA;
84 return !checkedA.IsValid();
85}
86
Jamie Madill5b772312018-03-08 20:28:32 -050087bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -040088{
89 switch (type)
90 {
91 // Types referenced in Table 3.4 of the ES 2.0.25 spec
92 case GL_UNSIGNED_BYTE:
93 case GL_UNSIGNED_SHORT_4_4_4_4:
94 case GL_UNSIGNED_SHORT_5_5_5_1:
95 case GL_UNSIGNED_SHORT_5_6_5:
96 return context->getClientVersion() >= ES_2_0;
97
98 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
99 case GL_BYTE:
100 case GL_INT:
101 case GL_SHORT:
102 case GL_UNSIGNED_INT:
103 case GL_UNSIGNED_INT_10F_11F_11F_REV:
104 case GL_UNSIGNED_INT_24_8:
105 case GL_UNSIGNED_INT_2_10_10_10_REV:
106 case GL_UNSIGNED_INT_5_9_9_9_REV:
107 case GL_UNSIGNED_SHORT:
108 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
109 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
110 return context->getClientVersion() >= ES_3_0;
111
112 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400113 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
114 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400115
116 case GL_HALF_FLOAT:
117 return context->getClientVersion() >= ES_3_0 ||
118 context->getExtensions().textureHalfFloat;
119
120 case GL_HALF_FLOAT_OES:
121 return context->getExtensions().colorBufferHalfFloat;
122
123 default:
124 return false;
125 }
126}
127
Jamie Madill5b772312018-03-08 20:28:32 -0500128bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400129{
130 switch (format)
131 {
132 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
133 case GL_RGBA:
134 case GL_RGB:
135 case GL_ALPHA:
136 return context->getClientVersion() >= ES_2_0;
137
138 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
139 case GL_RG:
140 case GL_RED:
141 case GL_RGBA_INTEGER:
142 case GL_RGB_INTEGER:
143 case GL_RG_INTEGER:
144 case GL_RED_INTEGER:
145 return context->getClientVersion() >= ES_3_0;
146
147 case GL_SRGB_ALPHA_EXT:
148 case GL_SRGB_EXT:
149 return context->getExtensions().sRGB;
150
151 case GL_BGRA_EXT:
152 return context->getExtensions().readFormatBGRA;
153
154 default:
155 return false;
156 }
157}
158
Jamie Madill5b772312018-03-08 20:28:32 -0500159bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400160 GLenum framebufferComponentType,
161 GLenum format,
162 GLenum type)
163{
164 switch (framebufferComponentType)
165 {
166 case GL_UNSIGNED_NORMALIZED:
167 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
168 // ReadPixels with BGRA even if the extension is not present
169 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
170 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
171 type == GL_UNSIGNED_BYTE);
172
173 case GL_SIGNED_NORMALIZED:
174 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
175
176 case GL_INT:
177 return (format == GL_RGBA_INTEGER && type == GL_INT);
178
179 case GL_UNSIGNED_INT:
180 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
181
182 case GL_FLOAT:
183 return (format == GL_RGBA && type == GL_FLOAT);
184
185 default:
186 UNREACHABLE();
187 return false;
188 }
189}
190
Geoff Langc1984ed2016-10-07 12:41:00 -0400191template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400192bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400193{
194 switch (ConvertToGLenum(params[0]))
195 {
196 case GL_CLAMP_TO_EDGE:
197 break;
198
Till Rathmannb8543632018-10-02 19:46:14 +0200199 case GL_CLAMP_TO_BORDER:
200 if (!context->getExtensions().textureBorderClamp)
201 {
Jamie Madille0472f32018-11-27 16:32:45 -0500202 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +0200203 return false;
204 }
205 break;
206
Geoff Langc1984ed2016-10-07 12:41:00 -0400207 case GL_REPEAT:
208 case GL_MIRRORED_REPEAT:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400209 if (restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400210 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400211 // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
Jamie Madille0472f32018-11-27 16:32:45 -0500212 context->validationError(GL_INVALID_ENUM, kInvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400213 return false;
214 }
215 break;
216
217 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500218 context->validationError(GL_INVALID_ENUM, kInvalidTextureWrap);
Geoff Langc1984ed2016-10-07 12:41:00 -0400219 return false;
220 }
221
222 return true;
223}
224
225template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400226bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400227{
228 switch (ConvertToGLenum(params[0]))
229 {
230 case GL_NEAREST:
231 case GL_LINEAR:
232 break;
233
234 case GL_NEAREST_MIPMAP_NEAREST:
235 case GL_LINEAR_MIPMAP_NEAREST:
236 case GL_NEAREST_MIPMAP_LINEAR:
237 case GL_LINEAR_MIPMAP_LINEAR:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400238 if (restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400239 {
240 // OES_EGL_image_external specifies this error.
Jamie Madille0472f32018-11-27 16:32:45 -0500241 context->validationError(GL_INVALID_ENUM, kInvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400242 return false;
243 }
244 break;
245
246 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500247 context->validationError(GL_INVALID_ENUM, kInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400248 return false;
249 }
250
251 return true;
252}
253
254template <typename ParamType>
255bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
256{
257 switch (ConvertToGLenum(params[0]))
258 {
259 case GL_NEAREST:
260 case GL_LINEAR:
261 break;
262
263 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500264 context->validationError(GL_INVALID_ENUM, kInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400265 return false;
266 }
267
268 return true;
269}
270
271template <typename ParamType>
272bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
273{
274 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
275 switch (ConvertToGLenum(params[0]))
276 {
277 case GL_NONE:
278 case GL_COMPARE_REF_TO_TEXTURE:
279 break;
280
281 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500282 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400283 return false;
284 }
285
286 return true;
287}
288
289template <typename ParamType>
290bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
291{
292 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
293 switch (ConvertToGLenum(params[0]))
294 {
295 case GL_LEQUAL:
296 case GL_GEQUAL:
297 case GL_LESS:
298 case GL_GREATER:
299 case GL_EQUAL:
300 case GL_NOTEQUAL:
301 case GL_ALWAYS:
302 case GL_NEVER:
303 break;
304
305 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500306 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400307 return false;
308 }
309
310 return true;
311}
312
313template <typename ParamType>
Geoff Lang81c6b572016-10-19 14:07:52 -0700314bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
315{
316 if (!context->getExtensions().textureSRGBDecode)
317 {
Jamie Madille0472f32018-11-27 16:32:45 -0500318 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang81c6b572016-10-19 14:07:52 -0700319 return false;
320 }
321
322 switch (ConvertToGLenum(params[0]))
323 {
324 case GL_DECODE_EXT:
325 case GL_SKIP_DECODE_EXT:
326 break;
327
328 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500329 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Lang81c6b572016-10-19 14:07:52 -0700330 return false;
331 }
332
333 return true;
334}
335
Luc Ferron1b1a8642018-01-23 15:12:01 -0500336bool ValidateTextureMaxAnisotropyExtensionEnabled(Context *context)
337{
338 if (!context->getExtensions().textureFilterAnisotropic)
339 {
Jamie Madille0472f32018-11-27 16:32:45 -0500340 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500341 return false;
342 }
343
344 return true;
345}
346
347bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
348{
349 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
350 {
351 return false;
352 }
353
354 GLfloat largest = context->getExtensions().maxTextureAnisotropy;
355
356 if (paramValue < 1 || paramValue > largest)
357 {
Jamie Madille0472f32018-11-27 16:32:45 -0500358 context->validationError(GL_INVALID_VALUE, kOutsideOfBounds);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500359 return false;
360 }
361
362 return true;
363}
364
Jamie Madill5b772312018-03-08 20:28:32 -0500365bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
Geoff Lange0cff192017-05-30 13:04:56 -0400366{
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500367 const Program *program = context->getState().getLinkedProgram(context);
368 const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
Geoff Lange0cff192017-05-30 13:04:56 -0400369
Jamie Madille7d80f32018-08-08 15:49:23 -0400370 return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
371 framebuffer->getDrawBufferTypeMask().to_ulong(),
372 program->getActiveOutputVariables().to_ulong(),
373 framebuffer->getDrawBufferMask().to_ulong());
Geoff Lange0cff192017-05-30 13:04:56 -0400374}
375
Jamie Madill5b772312018-03-08 20:28:32 -0500376bool ValidateVertexShaderAttributeTypeMatch(Context *context)
Geoff Lang9ab5b822017-05-30 16:19:23 -0400377{
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500378 const auto &glState = context->getState();
379 const Program *program = context->getState().getLinkedProgram(context);
380 const VertexArray *vao = context->getState().getVertexArray();
Geoff Lang9ab5b822017-05-30 16:19:23 -0400381
Brandon Jonesc405ae72017-12-06 14:15:03 -0800382 unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
383 unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
384 unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
385
386 vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
387 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
388 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
389
Jamie Madille7d80f32018-08-08 15:49:23 -0400390 return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
391 vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
392 0xFFFF);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400393}
394
Jamie Madill493f9572018-05-24 19:52:15 -0400395bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
396 PrimitiveMode geometryShaderInputPrimitiveType)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800397{
398 // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
Jamie Madill493f9572018-05-24 19:52:15 -0400399 switch (drawMode)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800400 {
Jamie Madill493f9572018-05-24 19:52:15 -0400401 case PrimitiveMode::Points:
402 return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
403 case PrimitiveMode::Lines:
404 case PrimitiveMode::LineStrip:
405 case PrimitiveMode::LineLoop:
406 return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
407 case PrimitiveMode::LinesAdjacency:
408 case PrimitiveMode::LineStripAdjacency:
409 return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
410 case PrimitiveMode::Triangles:
411 case PrimitiveMode::TriangleFan:
412 case PrimitiveMode::TriangleStrip:
413 return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
414 case PrimitiveMode::TrianglesAdjacency:
415 case PrimitiveMode::TriangleStripAdjacency:
416 return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
Jiawei Shaofccebff2018-03-08 13:51:02 +0800417 default:
418 UNREACHABLE();
419 return false;
420 }
421}
422
Lingfeng Yangf97641c2018-06-21 19:22:45 -0700423// GLES1 texture parameters are a small subset of the others
424bool IsValidGLES1TextureParameter(GLenum pname)
425{
426 switch (pname)
427 {
428 case GL_TEXTURE_MAG_FILTER:
429 case GL_TEXTURE_MIN_FILTER:
430 case GL_TEXTURE_WRAP_S:
431 case GL_TEXTURE_WRAP_T:
432 case GL_TEXTURE_WRAP_R:
433 case GL_GENERATE_MIPMAP:
434 case GL_TEXTURE_CROP_RECT_OES:
435 return true;
436 default:
437 return false;
438 }
439}
Till Rathmannb8543632018-10-02 19:46:14 +0200440
441unsigned int GetSamplerParameterCount(GLenum pname)
442{
443 return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
444}
445
Geoff Langf41a7152016-09-19 15:11:17 -0400446} // anonymous namespace
447
Brandon Jonesd1049182018-03-28 10:02:20 -0700448void SetRobustLengthParam(GLsizei *length, GLsizei value)
449{
450 if (length)
451 {
452 *length = value;
453 }
454}
455
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500456bool IsETC2EACFormat(const GLenum format)
457{
458 // ES 3.1, Table 8.19
459 switch (format)
460 {
461 case GL_COMPRESSED_R11_EAC:
462 case GL_COMPRESSED_SIGNED_R11_EAC:
463 case GL_COMPRESSED_RG11_EAC:
464 case GL_COMPRESSED_SIGNED_RG11_EAC:
465 case GL_COMPRESSED_RGB8_ETC2:
466 case GL_COMPRESSED_SRGB8_ETC2:
467 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
468 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
469 case GL_COMPRESSED_RGBA8_ETC2_EAC:
470 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
471 return true;
472
473 default:
474 return false;
475 }
476}
477
Jamie Madill5b772312018-03-08 20:28:32 -0500478bool ValidTextureTarget(const Context *context, TextureType type)
Jamie Madill35d15012013-10-07 10:46:37 -0400479{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800480 switch (type)
Jamie Madill35d15012013-10-07 10:46:37 -0400481 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800482 case TextureType::_2D:
483 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800484 return true;
Jamie Madill35d15012013-10-07 10:46:37 -0400485
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800486 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400487 return context->getExtensions().textureRectangle;
488
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800489 case TextureType::_3D:
490 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800491 return (context->getClientMajorVersion() >= 3);
Jamie Madilld7460c72014-01-21 16:38:14 -0500492
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800493 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800494 return (context->getClientVersion() >= Version(3, 1) ||
495 context->getExtensions().textureMultisample);
Olli Etuahod310a432018-08-24 15:40:23 +0300496 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300497 return context->getExtensions().textureStorageMultisample2DArray;
Geoff Lang3b573612016-10-31 14:08:10 -0400498
He Yunchaoced53ae2016-11-29 15:00:51 +0800499 default:
500 return false;
Jamie Madilld7460c72014-01-21 16:38:14 -0500501 }
Jamie Madill35d15012013-10-07 10:46:37 -0400502}
503
Jamie Madill5b772312018-03-08 20:28:32 -0500504bool ValidTexture2DTarget(const Context *context, TextureType type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500505{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800506 switch (type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500507 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800508 case TextureType::_2D:
509 case TextureType::CubeMap:
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500510 return true;
511
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800512 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400513 return context->getExtensions().textureRectangle;
514
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500515 default:
516 return false;
517 }
518}
519
Jamie Madill5b772312018-03-08 20:28:32 -0500520bool ValidTexture3DTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500521{
522 switch (target)
523 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800524 case TextureType::_3D:
525 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +0300526 return (context->getClientMajorVersion() >= 3);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500527
528 default:
529 return false;
530 }
531}
532
Ian Ewellbda75592016-04-18 17:25:54 -0400533// Most texture GL calls are not compatible with external textures, so we have a separate validation
534// function for use in the GL calls that do
Jamie Madill5b772312018-03-08 20:28:32 -0500535bool ValidTextureExternalTarget(const Context *context, TextureType target)
Ian Ewellbda75592016-04-18 17:25:54 -0400536{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800537 return (target == TextureType::External) &&
Ian Ewellbda75592016-04-18 17:25:54 -0400538 (context->getExtensions().eglImageExternal ||
539 context->getExtensions().eglStreamConsumerExternal);
540}
541
Shannon Woods4dfed832014-03-17 20:03:39 -0400542// This function differs from ValidTextureTarget in that the target must be
543// usable as the destination of a 2D operation-- so a cube face is valid, but
544// GL_TEXTURE_CUBE_MAP is not.
Jamie Madill560a8d82014-05-21 13:06:20 -0400545// Note: duplicate of IsInternalTextureTarget
Jamie Madill5b772312018-03-08 20:28:32 -0500546bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
Shannon Woods4dfed832014-03-17 20:03:39 -0400547{
548 switch (target)
549 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800550 case TextureTarget::_2D:
551 case TextureTarget::CubeMapNegativeX:
552 case TextureTarget::CubeMapNegativeY:
553 case TextureTarget::CubeMapNegativeZ:
554 case TextureTarget::CubeMapPositiveX:
555 case TextureTarget::CubeMapPositiveY:
556 case TextureTarget::CubeMapPositiveZ:
He Yunchaoced53ae2016-11-29 15:00:51 +0800557 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800558 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400559 return context->getExtensions().textureRectangle;
He Yunchaoced53ae2016-11-29 15:00:51 +0800560 default:
561 return false;
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500562 }
563}
564
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800565bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400566 PrimitiveMode transformFeedbackPrimitiveMode,
567 PrimitiveMode renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800568{
569 ASSERT(context);
570
571 if (!context->getExtensions().geometryShader)
572 {
573 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
574 // that does not match the current transform feedback object's draw mode (if transform
575 // feedback is active), (3.0.2, section 2.14, pg 86)
576 return transformFeedbackPrimitiveMode == renderPrimitiveMode;
577 }
578
579 // [GL_EXT_geometry_shader] Table 12.1gs
Jamie Madill493f9572018-05-24 19:52:15 -0400580 switch (renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800581 {
Jamie Madill493f9572018-05-24 19:52:15 -0400582 case PrimitiveMode::Points:
583 return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
584 case PrimitiveMode::Lines:
585 case PrimitiveMode::LineStrip:
586 case PrimitiveMode::LineLoop:
587 return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
588 case PrimitiveMode::Triangles:
589 case PrimitiveMode::TriangleFan:
590 case PrimitiveMode::TriangleStrip:
591 return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800592 default:
593 UNREACHABLE();
594 return false;
595 }
596}
597
Jamie Madill5b772312018-03-08 20:28:32 -0500598bool ValidateDrawElementsInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400599 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400600 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500601 DrawElementsType type,
Jamie Madillbe849e42017-05-02 15:49:00 -0400602 const GLvoid *indices,
603 GLsizei primcount)
604{
Jamie Madill9fa54ea2019-01-02 18:38:33 -0500605 if (primcount <= 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400606 {
Jamie Madill9fa54ea2019-01-02 18:38:33 -0500607 if (primcount < 0)
608 {
609 context->validationError(GL_INVALID_VALUE, kNegativePrimcount);
610 return false;
611 }
612
613 // Early exit.
614 return ValidateDrawElementsCommon(context, mode, count, type, indices, primcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400615 }
616
617 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount))
618 {
619 return false;
620 }
621
Jamie Madill9fa54ea2019-01-02 18:38:33 -0500622 if (count == 0)
623 {
624 // Early exit.
625 return true;
626 }
627
628 return ValidateDrawInstancedAttribs(context, primcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400629}
630
631bool ValidateDrawArraysInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400632 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400633 GLint first,
634 GLsizei count,
635 GLsizei primcount)
636{
Jamie Madill9fa54ea2019-01-02 18:38:33 -0500637 if (primcount <= 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400638 {
Jamie Madill9fa54ea2019-01-02 18:38:33 -0500639 if (primcount < 0)
640 {
641 context->validationError(GL_INVALID_VALUE, kNegativePrimcount);
642 return false;
643 }
644
645 // Early exit.
646 return ValidateDrawArraysCommon(context, mode, first, count, primcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400647 }
648
649 if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
650 {
651 return false;
652 }
653
Jamie Madill9fa54ea2019-01-02 18:38:33 -0500654 if (count == 0)
655 {
656 // Early exit.
657 return true;
658 }
659
660 return ValidateDrawInstancedAttribs(context, primcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400661}
662
Jamie Madill5b772312018-03-08 20:28:32 -0500663bool ValidateDrawInstancedANGLE(Context *context)
Jamie Madillbe849e42017-05-02 15:49:00 -0400664{
665 // Verify there is at least one active attribute with a divisor of zero
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500666 const State &state = context->getState();
Jamie Madillbe849e42017-05-02 15:49:00 -0400667
Jamie Madill785e8a02018-10-04 17:42:00 -0400668 Program *program = state.getLinkedProgram(context);
Jamie Madillbe849e42017-05-02 15:49:00 -0400669
670 const auto &attribs = state.getVertexArray()->getVertexAttributes();
671 const auto &bindings = state.getVertexArray()->getVertexBindings();
672 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
673 {
674 const VertexAttribute &attrib = attribs[attributeIndex];
675 const VertexBinding &binding = bindings[attrib.bindingIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +0300676 if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 {
678 return true;
679 }
680 }
681
Jamie Madille0472f32018-11-27 16:32:45 -0500682 context->validationError(GL_INVALID_OPERATION, kNoZeroDivisor);
Jamie Madillbe849e42017-05-02 15:49:00 -0400683 return false;
684}
685
Jamie Madill5b772312018-03-08 20:28:32 -0500686bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500687{
688 switch (target)
689 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800690 case TextureType::_3D:
691 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800692 return true;
693 default:
694 return false;
Shannon Woods4dfed832014-03-17 20:03:39 -0400695 }
696}
697
Jamie Madill5b772312018-03-08 20:28:32 -0500698bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
He Yunchao11b038b2016-11-22 21:24:04 +0800699{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800700 switch (type)
He Yunchao11b038b2016-11-22 21:24:04 +0800701 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800702 case TextureType::_2D:
703 case TextureType::_2DArray:
704 case TextureType::_2DMultisample:
705 case TextureType::CubeMap:
706 case TextureType::_3D:
He Yunchao11b038b2016-11-22 21:24:04 +0800707 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800708 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400709 return context->getExtensions().textureRectangle;
Olli Etuahod310a432018-08-24 15:40:23 +0300710 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300711 return context->getExtensions().textureStorageMultisample2DArray;
He Yunchao11b038b2016-11-22 21:24:04 +0800712 default:
713 return false;
714 }
715}
716
Jamie Madill5b772312018-03-08 20:28:32 -0500717bool ValidFramebufferTarget(const Context *context, GLenum target)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500718{
He Yunchaoced53ae2016-11-29 15:00:51 +0800719 static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
720 GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
Geoff Langd4475812015-03-18 10:53:05 -0400721 "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500722
723 switch (target)
724 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800725 case GL_FRAMEBUFFER:
726 return true;
Geoff Lange8afa902017-09-27 15:00:43 -0400727
He Yunchaoced53ae2016-11-29 15:00:51 +0800728 case GL_READ_FRAMEBUFFER:
He Yunchaoced53ae2016-11-29 15:00:51 +0800729 case GL_DRAW_FRAMEBUFFER:
Geoff Lange8afa902017-09-27 15:00:43 -0400730 return (context->getExtensions().framebufferBlit ||
731 context->getClientMajorVersion() >= 3);
732
He Yunchaoced53ae2016-11-29 15:00:51 +0800733 default:
734 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500735 }
736}
737
Jamie Madill5b772312018-03-08 20:28:32 -0500738bool ValidMipLevel(const Context *context, TextureType type, GLint level)
Geoff Langce635692013-09-24 13:56:32 -0400739{
Jamie Madillc29968b2016-01-20 11:17:23 -0500740 const auto &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -0400741 size_t maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800742 switch (type)
Geoff Langce635692013-09-24 13:56:32 -0400743 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800744 case TextureType::_2D:
745 case TextureType::_2DArray:
746 case TextureType::_2DMultisample:
Olli Etuahod310a432018-08-24 15:40:23 +0300747 case TextureType::_2DMultisampleArray:
748 // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
749 // level-of-detail" for multisample textures should be. Could maybe make it zero.
Jamie Madillc29968b2016-01-20 11:17:23 -0500750 maxDimension = caps.max2DTextureSize;
751 break;
Geoff Langbe607ad2018-11-29 10:14:22 -0500752
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800753 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800754 maxDimension = caps.maxCubeMapTextureSize;
755 break;
Geoff Langbe607ad2018-11-29 10:14:22 -0500756
757 case TextureType::External:
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800758 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400759 return level == 0;
Geoff Langbe607ad2018-11-29 10:14:22 -0500760
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800761 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800762 maxDimension = caps.max3DTextureSize;
763 break;
Geoff Langbe607ad2018-11-29 10:14:22 -0500764
He Yunchaoced53ae2016-11-29 15:00:51 +0800765 default:
766 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400767 }
768
Jamie Madill43da7c42018-08-01 11:34:49 -0400769 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400770}
771
Jamie Madill5b772312018-03-08 20:28:32 -0500772bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800773 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700774 GLint level,
775 GLsizei width,
776 GLsizei height,
777 GLsizei depth,
778 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400779{
Brandon Jones6cad5662017-06-14 13:25:13 -0700780 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400781 {
Jamie Madille0472f32018-11-27 16:32:45 -0500782 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400783 return false;
784 }
Austin Kinross08528e12015-10-07 16:24:40 -0700785 // TexSubImage parameters can be NPOT without textureNPOT extension,
786 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500787 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500788 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500789 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400790 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400791 {
Jamie Madille0472f32018-11-27 16:32:45 -0500792 context->validationError(GL_INVALID_VALUE, kTextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400793 return false;
794 }
795
796 if (!ValidMipLevel(context, target, level))
797 {
Jamie Madille0472f32018-11-27 16:32:45 -0500798 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400799 return false;
800 }
801
802 return true;
803}
804
Geoff Lang966c9402017-04-18 12:38:27 -0400805bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
806{
807 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
808 (size % blockSize == 0);
809}
810
Jamie Madill5b772312018-03-08 20:28:32 -0500811bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500812 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400813 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500814 GLsizei width,
815 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400816{
Jamie Madill43da7c42018-08-01 11:34:49 -0400817 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400818 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400819 {
820 return false;
821 }
822
Geoff Lang966c9402017-04-18 12:38:27 -0400823 if (width < 0 || height < 0)
824 {
825 return false;
826 }
827
828 if (CompressedTextureFormatRequiresExactSize(internalFormat))
829 {
830 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
831 // block size for level 0 but WebGL disallows this.
832 bool smallerThanBlockSizeAllowed =
833 level > 0 || !context->getExtensions().webglCompatibility;
834
835 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
836 smallerThanBlockSizeAllowed) ||
837 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
838 smallerThanBlockSizeAllowed))
839 {
840 return false;
841 }
842 }
843
844 return true;
845}
846
Jamie Madill5b772312018-03-08 20:28:32 -0500847bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400848 GLenum internalFormat,
849 GLint xoffset,
850 GLint yoffset,
851 GLsizei width,
852 GLsizei height,
853 size_t textureWidth,
854 size_t textureHeight)
855{
Jamie Madill43da7c42018-08-01 11:34:49 -0400856 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400857 if (!formatInfo.compressed)
858 {
859 return false;
860 }
861
Geoff Lang44ff5a72017-02-03 15:15:43 -0500862 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400863 {
864 return false;
865 }
866
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500867 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400868 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500869 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400870 yoffset % formatInfo.compressedBlockHeight != 0)
871 {
872 return false;
873 }
874
875 // Allowed to either have data that is a multiple of block size or is smaller than the block
876 // size but fills the entire mip
877 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
878 static_cast<size_t>(width) == textureWidth &&
879 static_cast<size_t>(height) == textureHeight;
880 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
881 (height % formatInfo.compressedBlockHeight) == 0;
882 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400883 {
884 return false;
885 }
886 }
887
Geoff Langd4f180b2013-09-24 13:57:44 -0400888 return true;
889}
890
Jamie Madill5b772312018-03-08 20:28:32 -0500891bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800892 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400893 GLsizei width,
894 GLsizei height,
895 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400896 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400897 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400898 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400899 GLsizei imageSize)
900{
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500901 Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400902 if (pixelUnpackBuffer == nullptr && imageSize < 0)
903 {
904 // Checks are not required
905 return true;
906 }
907
908 // ...the data would be unpacked from the buffer object such that the memory reads required
909 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400910 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400911 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400912 const Extents size(width, height, depth);
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500913 const auto &unpack = context->getState().getUnpackState();
Geoff Langff5b2d52016-09-07 11:32:23 -0400914
Jamie Madill7f232932018-09-12 11:03:06 -0400915 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
916 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400917 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400918 {
Jamie Madille0472f32018-11-27 16:32:45 -0500919 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400920 return false;
921 }
922
Geoff Langff5b2d52016-09-07 11:32:23 -0400923 if (pixelUnpackBuffer)
924 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400925 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400926 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
927 checkedEndByte += checkedOffset;
928
929 if (!checkedEndByte.IsValid() ||
930 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
931 {
932 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -0500933 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400934 return false;
935 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800936 if (context->getExtensions().webglCompatibility &&
937 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
938 {
Jamie Madill610640f2018-11-21 17:28:41 -0500939 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -0500940 kPixelUnpackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -0800941 return false;
942 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400943 }
944 else
945 {
946 ASSERT(imageSize >= 0);
947 if (pixels == nullptr && imageSize != 0)
948 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500949 context->validationError(GL_INVALID_OPERATION, kImageSizeMustBeZero);
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400950 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400951 }
952
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400953 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400954 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500955 context->validationError(GL_INVALID_OPERATION, kImageSizeTooSmall);
Geoff Langff5b2d52016-09-07 11:32:23 -0400956 return false;
957 }
958 }
959
960 return true;
961}
962
Corentin Wallezad3ae902018-03-09 13:40:42 -0500963bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500964{
Geoff Lang37dde692014-01-31 16:34:54 -0500965 switch (queryType)
966 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500967 case QueryType::AnySamples:
968 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400969 return context->getClientMajorVersion() >= 3 ||
970 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500971 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800972 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500973 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800974 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500975 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800976 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500977 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800978 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800979 default:
980 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500981 }
982}
983
Jamie Madill5b772312018-03-08 20:28:32 -0500984bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400985 GLenum type,
986 GLboolean normalized,
987 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400988 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400989 bool pureInteger)
990{
991 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -0400992 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
993 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
994 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
995 // parameter exceeds 255.
996 constexpr GLsizei kMaxWebGLStride = 255;
997 if (stride > kMaxWebGLStride)
998 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500999 context->validationError(GL_INVALID_VALUE, kStrideExceedsWebGLLimit);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001000 return false;
1001 }
1002
1003 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1004 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1005 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1006 // or an INVALID_OPERATION error is generated.
Frank Henigmand633b152018-10-04 23:34:31 -04001007 angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1008 size_t typeSize = GetVertexFormatSize(internalType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001009
1010 ASSERT(isPow2(typeSize) && typeSize > 0);
1011 size_t sizeMask = (typeSize - 1);
1012 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1013 {
Jamie Madille0472f32018-11-27 16:32:45 -05001014 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001015 return false;
1016 }
1017
1018 if ((stride & sizeMask) != 0)
1019 {
Jamie Madille0472f32018-11-27 16:32:45 -05001020 context->validationError(GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001021 return false;
1022 }
1023
1024 return true;
1025}
1026
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001027Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001028{
He Yunchaoced53ae2016-11-29 15:00:51 +08001029 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1030 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1031 // or program object and INVALID_OPERATION if the provided name identifies an object
1032 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001033
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001034 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001035
1036 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001037 {
Dian Xiang769769a2015-09-09 15:20:08 -07001038 if (context->getShader(id))
1039 {
Jamie Madille0472f32018-11-27 16:32:45 -05001040 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001041 }
1042 else
1043 {
Jamie Madille0472f32018-11-27 16:32:45 -05001044 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001045 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001046 }
Dian Xiang769769a2015-09-09 15:20:08 -07001047
1048 return validProgram;
1049}
1050
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001051Program *GetValidProgram(Context *context, GLuint id)
1052{
1053 Program *program = GetValidProgramNoResolve(context, id);
1054 if (program)
1055 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001056 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001057 }
1058 return program;
1059}
1060
Jamie Madill5b772312018-03-08 20:28:32 -05001061Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001062{
1063 // See ValidProgram for spec details.
1064
1065 Shader *validShader = context->getShader(id);
1066
1067 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001068 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001069 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001070 {
Jamie Madille0472f32018-11-27 16:32:45 -05001071 context->validationError(GL_INVALID_OPERATION, kExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001072 }
1073 else
1074 {
Jamie Madille0472f32018-11-27 16:32:45 -05001075 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001076 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001077 }
Dian Xiang769769a2015-09-09 15:20:08 -07001078
1079 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001080}
1081
Jamie Madill43da7c42018-08-01 11:34:49 -04001082bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001083{
Geoff Langfa125c92017-10-24 13:01:46 -04001084 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001085 {
Geoff Langfa125c92017-10-24 13:01:46 -04001086 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1087 {
Jamie Madille0472f32018-11-27 16:32:45 -05001088 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langfa125c92017-10-24 13:01:46 -04001089 return false;
1090 }
Jamie Madillb4472272014-07-03 10:38:55 -04001091
Geoff Langfa125c92017-10-24 13:01:46 -04001092 // Color attachment 0 is validated below because it is always valid
1093 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001094 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001095 {
Jamie Madille0472f32018-11-27 16:32:45 -05001096 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001097 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001098 }
1099 }
1100 else
1101 {
1102 switch (attachment)
1103 {
Geoff Langfa125c92017-10-24 13:01:46 -04001104 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001105 case GL_DEPTH_ATTACHMENT:
1106 case GL_STENCIL_ATTACHMENT:
1107 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001108
He Yunchaoced53ae2016-11-29 15:00:51 +08001109 case GL_DEPTH_STENCIL_ATTACHMENT:
1110 if (!context->getExtensions().webglCompatibility &&
1111 context->getClientMajorVersion() < 3)
1112 {
Jamie Madille0472f32018-11-27 16:32:45 -05001113 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001114 return false;
1115 }
1116 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001117
He Yunchaoced53ae2016-11-29 15:00:51 +08001118 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001119 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001120 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001121 }
1122 }
1123
1124 return true;
1125}
1126
Jamie Madill5b772312018-03-08 20:28:32 -05001127bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001128 GLenum target,
1129 GLsizei samples,
1130 GLenum internalformat,
1131 GLsizei width,
1132 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001133{
1134 switch (target)
1135 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001136 case GL_RENDERBUFFER:
1137 break;
1138 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001139 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001140 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001141 }
1142
1143 if (width < 0 || height < 0 || samples < 0)
1144 {
Jamie Madille0472f32018-11-27 16:32:45 -05001145 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001146 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001147 }
1148
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001149 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1150 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1151
1152 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001153 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 {
Jamie Madille0472f32018-11-27 16:32:45 -05001155 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001156 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 }
1158
1159 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1160 // 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 -08001161 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001162 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001163 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001164 {
Jamie Madille0472f32018-11-27 16:32:45 -05001165 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001166 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 }
1168
Geoff Langaae65a42014-05-26 12:43:44 -04001169 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170 {
Jamie Madille0472f32018-11-27 16:32:45 -05001171 context->validationError(GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 }
1174
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001175 GLuint handle = context->getState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001176 if (handle == 0)
1177 {
Jamie Madille0472f32018-11-27 16:32:45 -05001178 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001179 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001180 }
1181
1182 return true;
1183}
1184
Jamie Madill43da7c42018-08-01 11:34:49 -04001185bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 GLenum target,
1187 GLenum attachment,
1188 GLenum renderbuffertarget,
1189 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001190{
Geoff Lange8afa902017-09-27 15:00:43 -04001191 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001192 {
Jamie Madille0472f32018-11-27 16:32:45 -05001193 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001194 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001195 }
1196
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001197 Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001198
Jamie Madill84115c92015-04-23 15:00:07 -04001199 ASSERT(framebuffer);
1200 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001201 {
Jamie Madille0472f32018-11-27 16:32:45 -05001202 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001203 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001204 }
1205
Jamie Madillb4472272014-07-03 10:38:55 -04001206 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001207 {
Jamie Madillb4472272014-07-03 10:38:55 -04001208 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209 }
1210
Jamie Madillab9d82c2014-01-21 16:38:14 -05001211 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1212 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1213 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1214 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1215 if (renderbuffer != 0)
1216 {
1217 if (!context->getRenderbuffer(renderbuffer))
1218 {
Jamie Madille0472f32018-11-27 16:32:45 -05001219 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001220 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001221 }
1222 }
1223
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001224 return true;
1225}
1226
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001227bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001228 GLint srcX0,
1229 GLint srcY0,
1230 GLint srcX1,
1231 GLint srcY1,
1232 GLint dstX0,
1233 GLint dstY0,
1234 GLint dstX1,
1235 GLint dstY1,
1236 GLbitfield mask,
1237 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001238{
1239 switch (filter)
1240 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001241 case GL_NEAREST:
1242 break;
1243 case GL_LINEAR:
1244 break;
1245 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001246 context->validationError(GL_INVALID_ENUM, kBlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001247 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001248 }
1249
1250 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1251 {
Jamie Madille0472f32018-11-27 16:32:45 -05001252 context->validationError(GL_INVALID_VALUE, kBlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001253 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001254 }
1255
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001256 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1257 // color buffer, leaving only nearest being unfiltered from above
1258 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1259 {
Jamie Madille0472f32018-11-27 16:32:45 -05001260 context->validationError(GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001261 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 }
1263
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001264 const auto &glState = context->getState();
Jamie Madill7f232932018-09-12 11:03:06 -04001265 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1266 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001267
1268 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 {
Jamie Madille0472f32018-11-27 16:32:45 -05001270 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001271 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001272 }
1273
Jamie Madill427064d2018-04-13 16:20:34 -04001274 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001275 {
Jamie Madill48faf802014-11-06 15:27:22 -05001276 return false;
1277 }
1278
Jamie Madill427064d2018-04-13 16:20:34 -04001279 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001280 {
Jamie Madill48faf802014-11-06 15:27:22 -05001281 return false;
1282 }
1283
Qin Jiajiaaef92162018-02-27 13:51:44 +08001284 if (readFramebuffer->id() == drawFramebuffer->id())
1285 {
Jamie Madille0472f32018-11-27 16:32:45 -05001286 context->validationError(GL_INVALID_OPERATION, kBlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001287 return false;
1288 }
1289
Jamie Madille98b1b52018-03-08 09:47:23 -05001290 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001291 {
Geoff Langb1196682014-07-23 13:47:29 -04001292 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001293 }
1294
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001295 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1296 // always run it in order to avoid triggering driver bugs.
1297 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1298 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001299 {
Jamie Madille0472f32018-11-27 16:32:45 -05001300 context->validationError(GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001301 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001302 }
1303
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001304 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1305
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001306 if (mask & GL_COLOR_BUFFER_BIT)
1307 {
Jamie Madill7f232932018-09-12 11:03:06 -04001308 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1309 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001310
He Yunchao66a41a22016-12-15 16:45:05 +08001311 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001312 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001313 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001314
Geoff Langa15472a2015-08-11 11:48:03 -04001315 for (size_t drawbufferIdx = 0;
1316 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001317 {
Geoff Langa15472a2015-08-11 11:48:03 -04001318 const FramebufferAttachment *attachment =
1319 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1320 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001321 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001322 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001323
Geoff Langb2f3d052013-08-13 12:49:27 -04001324 // The GL ES 3.0.2 spec (pg 193) states that:
1325 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001326 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1327 // as well
1328 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1329 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001330 // Changes with EXT_color_buffer_float:
1331 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001332 GLenum readComponentType = readFormat.info->componentType;
1333 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001335 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001336 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001337 drawComponentType == GL_SIGNED_NORMALIZED);
1338
1339 if (extensions.colorBufferFloat)
1340 {
1341 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1342 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1343
1344 if (readFixedOrFloat != drawFixedOrFloat)
1345 {
Jamie Madill610640f2018-11-21 17:28:41 -05001346 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001347 kBlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001348 return false;
1349 }
1350 }
1351 else if (readFixedPoint != drawFixedPoint)
1352 {
Jamie Madille0472f32018-11-27 16:32:45 -05001353 context->validationError(GL_INVALID_OPERATION, kBlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001354 return false;
1355 }
1356
1357 if (readComponentType == GL_UNSIGNED_INT &&
1358 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001359 {
Jamie Madill610640f2018-11-21 17:28:41 -05001360 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001361 kBlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001362 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001363 }
1364
Jamie Madill6163c752015-12-07 16:32:59 -05001365 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001366 {
Jamie Madill610640f2018-11-21 17:28:41 -05001367 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001368 kBlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001369 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001370 }
1371
Jamie Madilla3944d42016-07-22 22:13:26 -04001372 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001373 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 {
Jamie Madill610640f2018-11-21 17:28:41 -05001375 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001376 kBlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001377 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001378 }
Geoff Lange4915782017-04-12 15:19:07 -04001379
1380 if (context->getExtensions().webglCompatibility &&
1381 *readColorBuffer == *attachment)
1382 {
Jamie Madille0472f32018-11-27 16:32:45 -05001383 context->validationError(GL_INVALID_OPERATION, kBlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001384 return false;
1385 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001386 }
1387 }
1388
Jamie Madilla3944d42016-07-22 22:13:26 -04001389 if ((readFormat.info->componentType == GL_INT ||
1390 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1391 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001392 {
Jamie Madille0472f32018-11-27 16:32:45 -05001393 context->validationError(GL_INVALID_OPERATION, kBlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001394 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001395 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001396 }
He Yunchao66a41a22016-12-15 16:45:05 +08001397 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1398 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1399 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1400 // situation is an application error that would lead to a crash in ANGLE.
1401 else if (drawFramebuffer->hasEnabledDrawBuffer())
1402 {
Jamie Madille0472f32018-11-27 16:32:45 -05001403 context->validationError(GL_INVALID_OPERATION, kBlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001404 return false;
1405 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001406 }
1407
He Yunchaoced53ae2016-11-29 15:00:51 +08001408 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001409 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1410 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001411 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001412 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001413 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001414 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001415 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001416 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001417 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001419 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001420 {
Kenneth Russell69382852017-07-21 16:38:44 -04001421 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001422 {
Jamie Madill610640f2018-11-21 17:28:41 -05001423 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001424 kBlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001425 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001426 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001427
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001428 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001429 {
Jamie Madille0472f32018-11-27 16:32:45 -05001430 context->validationError(GL_INVALID_OPERATION, kBlitMultisampledBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001431 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001432 }
Geoff Lange4915782017-04-12 15:19:07 -04001433
1434 if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer)
1435 {
Jamie Madille0472f32018-11-27 16:32:45 -05001436 context->validationError(GL_INVALID_OPERATION, kBlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001437 return false;
1438 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001439 }
He Yunchao66a41a22016-12-15 16:45:05 +08001440 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1441 else if (drawBuffer)
1442 {
Jamie Madille0472f32018-11-27 16:32:45 -05001443 context->validationError(GL_INVALID_OPERATION, kBlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001444 return false;
1445 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001446 }
1447 }
1448
Martin Radeva3ed4572017-07-27 18:29:37 +03001449 // ANGLE_multiview, Revision 1:
1450 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001451 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1452 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1453 // views in the current read framebuffer is more than one.
1454 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001455 {
Jamie Madille0472f32018-11-27 16:32:45 -05001456 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001457 return false;
1458 }
1459 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1460 {
Jamie Madille0472f32018-11-27 16:32:45 -05001461 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001462 return false;
1463 }
1464
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001465 return true;
1466}
1467
Jamie Madill4928b7c2017-06-20 12:57:39 -04001468bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001469 GLint x,
1470 GLint y,
1471 GLsizei width,
1472 GLsizei height,
1473 GLenum format,
1474 GLenum type,
1475 GLsizei bufSize,
1476 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001477 GLsizei *columns,
1478 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001479 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001480{
1481 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001482 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001483 return false;
1484 }
1485
Brandon Jonesd1049182018-03-28 10:02:20 -07001486 GLsizei writeLength = 0;
1487 GLsizei writeColumns = 0;
1488 GLsizei writeRows = 0;
1489
1490 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1491 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001492 {
Geoff Langb1196682014-07-23 13:47:29 -04001493 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001494 }
1495
Brandon Jonesd1049182018-03-28 10:02:20 -07001496 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001497 {
Geoff Langb1196682014-07-23 13:47:29 -04001498 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001499 }
1500
Brandon Jonesd1049182018-03-28 10:02:20 -07001501 SetRobustLengthParam(length, writeLength);
1502 SetRobustLengthParam(columns, writeColumns);
1503 SetRobustLengthParam(rows, writeRows);
1504
Jamie Madillc29968b2016-01-20 11:17:23 -05001505 return true;
1506}
1507
1508bool ValidateReadnPixelsEXT(Context *context,
1509 GLint x,
1510 GLint y,
1511 GLsizei width,
1512 GLsizei height,
1513 GLenum format,
1514 GLenum type,
1515 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001516 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001517{
1518 if (bufSize < 0)
1519 {
Jamie Madille0472f32018-11-27 16:32:45 -05001520 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001521 return false;
1522 }
1523
Geoff Lang62fce5b2016-09-30 10:46:35 -04001524 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001525 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001526}
Jamie Madill26e91952014-03-05 15:01:27 -05001527
Jamie Madill4928b7c2017-06-20 12:57:39 -04001528bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001529 GLint x,
1530 GLint y,
1531 GLsizei width,
1532 GLsizei height,
1533 GLenum format,
1534 GLenum type,
1535 GLsizei bufSize,
1536 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001537 GLsizei *columns,
1538 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001539 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001540{
Brandon Jonesd1049182018-03-28 10:02:20 -07001541 GLsizei writeLength = 0;
1542 GLsizei writeColumns = 0;
1543 GLsizei writeRows = 0;
1544
Geoff Lang62fce5b2016-09-30 10:46:35 -04001545 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001546 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001547 return false;
1548 }
1549
Brandon Jonesd1049182018-03-28 10:02:20 -07001550 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1551 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001552 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001553 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001554 }
1555
Brandon Jonesd1049182018-03-28 10:02:20 -07001556 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001557 {
1558 return false;
1559 }
1560
Brandon Jonesd1049182018-03-28 10:02:20 -07001561 SetRobustLengthParam(length, writeLength);
1562 SetRobustLengthParam(columns, writeColumns);
1563 SetRobustLengthParam(rows, writeRows);
1564
Geoff Lang62fce5b2016-09-30 10:46:35 -04001565 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001566}
1567
Jamie Madill43da7c42018-08-01 11:34:49 -04001568bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001569{
1570 if (!context->getExtensions().occlusionQueryBoolean &&
1571 !context->getExtensions().disjointTimerQuery)
1572 {
Jamie Madille0472f32018-11-27 16:32:45 -05001573 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001574 return false;
1575 }
1576
Olli Etuaho41997e72016-03-10 13:38:39 +02001577 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001578}
1579
Jamie Madill43da7c42018-08-01 11:34:49 -04001580bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001581{
1582 if (!context->getExtensions().occlusionQueryBoolean &&
1583 !context->getExtensions().disjointTimerQuery)
1584 {
Jamie Madille0472f32018-11-27 16:32:45 -05001585 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001586 return false;
1587 }
1588
Olli Etuaho41997e72016-03-10 13:38:39 +02001589 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001590}
1591
Jamie Madill43da7c42018-08-01 11:34:49 -04001592bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001593{
1594 if (!context->getExtensions().occlusionQueryBoolean &&
1595 !context->getExtensions().disjointTimerQuery)
1596 {
Jamie Madille0472f32018-11-27 16:32:45 -05001597 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Jamie Madillf0e04492017-08-26 15:28:42 -04001598 return false;
1599 }
1600
1601 return true;
1602}
1603
Jamie Madill43da7c42018-08-01 11:34:49 -04001604bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001605{
1606 if (!ValidQueryType(context, target))
1607 {
Jamie Madille0472f32018-11-27 16:32:45 -05001608 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001609 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001610 }
1611
1612 if (id == 0)
1613 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001614 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001615 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001616 }
1617
1618 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1619 // of zero, if the active query object name for <target> is non-zero (for the
1620 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1621 // the active query for either target is non-zero), if <id> is the name of an
1622 // existing query object whose type does not match <target>, or if <id> is the
1623 // active query object name for any query type, the error INVALID_OPERATION is
1624 // generated.
1625
1626 // Ensure no other queries are active
1627 // NOTE: If other queries than occlusion are supported, we will need to check
1628 // separately that:
1629 // a) The query ID passed is not the current active query for any target/type
1630 // b) There are no active queries for the requested target (and in the case
1631 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1632 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001633
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001634 if (context->getState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001635 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001636 context->validationError(GL_INVALID_OPERATION, kOtherQueryActive);
Geoff Langb1196682014-07-23 13:47:29 -04001637 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001638 }
1639
1640 Query *queryObject = context->getQuery(id, true, target);
1641
1642 // check that name was obtained with glGenQueries
1643 if (!queryObject)
1644 {
Jamie Madille0472f32018-11-27 16:32:45 -05001645 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001646 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001647 }
1648
1649 // check for type mismatch
1650 if (queryObject->getType() != target)
1651 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001652 context->validationError(GL_INVALID_OPERATION, kQueryTargetMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001653 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001654 }
1655
1656 return true;
1657}
1658
Jamie Madill43da7c42018-08-01 11:34:49 -04001659bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001660{
1661 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001662 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001663 {
Jamie Madille0472f32018-11-27 16:32:45 -05001664 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001665 return false;
1666 }
1667
1668 return ValidateBeginQueryBase(context, target, id);
1669}
1670
Jamie Madill43da7c42018-08-01 11:34:49 -04001671bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001672{
1673 if (!ValidQueryType(context, target))
1674 {
Jamie Madille0472f32018-11-27 16:32:45 -05001675 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001676 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001677 }
1678
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001679 const Query *queryObject = context->getState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001680
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001681 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001682 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001683 context->validationError(GL_INVALID_OPERATION, kQueryInactive);
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001685 }
1686
Jamie Madill45c785d2014-05-13 14:09:34 -04001687 return true;
1688}
1689
Jamie Madill43da7c42018-08-01 11:34:49 -04001690bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001691{
1692 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001693 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001694 {
Jamie Madille0472f32018-11-27 16:32:45 -05001695 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001696 return false;
1697 }
1698
1699 return ValidateEndQueryBase(context, target);
1700}
1701
Corentin Wallezad3ae902018-03-09 13:40:42 -05001702bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001703{
1704 if (!context->getExtensions().disjointTimerQuery)
1705 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001706 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001707 return false;
1708 }
1709
Corentin Wallezad3ae902018-03-09 13:40:42 -05001710 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001711 {
Jamie Madille0472f32018-11-27 16:32:45 -05001712 context->validationError(GL_INVALID_ENUM, kInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001713 return false;
1714 }
1715
1716 Query *queryObject = context->getQuery(id, true, target);
1717 if (queryObject == nullptr)
1718 {
Jamie Madille0472f32018-11-27 16:32:45 -05001719 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001720 return false;
1721 }
1722
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001723 if (context->getState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001724 {
Jamie Madille0472f32018-11-27 16:32:45 -05001725 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001726 return false;
1727 }
1728
1729 return true;
1730}
1731
Corentin Wallezad3ae902018-03-09 13:40:42 -05001732bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001733{
Geoff Lang2186c382016-10-14 10:54:54 -04001734 if (numParams)
1735 {
1736 *numParams = 0;
1737 }
1738
Corentin Wallezad3ae902018-03-09 13:40:42 -05001739 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001740 {
Jamie Madille0472f32018-11-27 16:32:45 -05001741 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001742 return false;
1743 }
1744
1745 switch (pname)
1746 {
1747 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001748 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001749 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001750 context->validationError(GL_INVALID_ENUM, kInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001751 return false;
1752 }
1753 break;
1754 case GL_QUERY_COUNTER_BITS_EXT:
1755 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001756 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001757 {
Jamie Madille0472f32018-11-27 16:32:45 -05001758 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001759 return false;
1760 }
1761 break;
1762 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001763 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001764 return false;
1765 }
1766
Geoff Lang2186c382016-10-14 10:54:54 -04001767 if (numParams)
1768 {
1769 // All queries return only one value
1770 *numParams = 1;
1771 }
1772
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001773 return true;
1774}
1775
Corentin Wallezad3ae902018-03-09 13:40:42 -05001776bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001777{
1778 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001779 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001780 {
Jamie Madille0472f32018-11-27 16:32:45 -05001781 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001782 return false;
1783 }
1784
Geoff Lang2186c382016-10-14 10:54:54 -04001785 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001786}
1787
Geoff Lang2186c382016-10-14 10:54:54 -04001788bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001789 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001790 GLenum pname,
1791 GLsizei bufSize,
1792 GLsizei *length,
1793 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001794{
Geoff Lang2186c382016-10-14 10:54:54 -04001795 if (!ValidateRobustEntryPoint(context, bufSize))
1796 {
1797 return false;
1798 }
1799
Brandon Jonesd1049182018-03-28 10:02:20 -07001800 GLsizei numParams = 0;
1801
1802 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001803 {
1804 return false;
1805 }
1806
Brandon Jonesd1049182018-03-28 10:02:20 -07001807 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001808 {
1809 return false;
1810 }
1811
Brandon Jonesd1049182018-03-28 10:02:20 -07001812 SetRobustLengthParam(length, numParams);
1813
Geoff Lang2186c382016-10-14 10:54:54 -04001814 return true;
1815}
1816
1817bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1818{
1819 if (numParams)
1820 {
1821 *numParams = 0;
1822 }
1823
Corentin Wallezad3ae902018-03-09 13:40:42 -05001824 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001825
1826 if (!queryObject)
1827 {
Jamie Madille0472f32018-11-27 16:32:45 -05001828 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001829 return false;
1830 }
1831
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001832 if (context->getState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001833 {
Jamie Madille0472f32018-11-27 16:32:45 -05001834 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001835 return false;
1836 }
1837
1838 switch (pname)
1839 {
1840 case GL_QUERY_RESULT_EXT:
1841 case GL_QUERY_RESULT_AVAILABLE_EXT:
1842 break;
1843
1844 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001845 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001846 return false;
1847 }
1848
Geoff Lang2186c382016-10-14 10:54:54 -04001849 if (numParams)
1850 {
1851 *numParams = 1;
1852 }
1853
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001854 return true;
1855}
1856
1857bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1858{
1859 if (!context->getExtensions().disjointTimerQuery)
1860 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001861 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001862 return false;
1863 }
Geoff Lang2186c382016-10-14 10:54:54 -04001864 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1865}
1866
1867bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1868 GLuint id,
1869 GLenum pname,
1870 GLsizei bufSize,
1871 GLsizei *length,
1872 GLint *params)
1873{
1874 if (!context->getExtensions().disjointTimerQuery)
1875 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001876 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001877 return false;
1878 }
1879
1880 if (!ValidateRobustEntryPoint(context, bufSize))
1881 {
1882 return false;
1883 }
1884
Brandon Jonesd1049182018-03-28 10:02:20 -07001885 GLsizei numParams = 0;
1886
1887 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001888 {
1889 return false;
1890 }
1891
Brandon Jonesd1049182018-03-28 10:02:20 -07001892 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001893 {
1894 return false;
1895 }
1896
Brandon Jonesd1049182018-03-28 10:02:20 -07001897 SetRobustLengthParam(length, numParams);
1898
Geoff Lang2186c382016-10-14 10:54:54 -04001899 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001900}
1901
1902bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1903{
1904 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001905 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001906 {
Jamie Madille0472f32018-11-27 16:32:45 -05001907 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001908 return false;
1909 }
Geoff Lang2186c382016-10-14 10:54:54 -04001910 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1911}
1912
1913bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1914 GLuint id,
1915 GLenum pname,
1916 GLsizei bufSize,
1917 GLsizei *length,
1918 GLuint *params)
1919{
1920 if (!context->getExtensions().disjointTimerQuery &&
1921 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1922 {
Jamie Madille0472f32018-11-27 16:32:45 -05001923 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001924 return false;
1925 }
1926
1927 if (!ValidateRobustEntryPoint(context, bufSize))
1928 {
1929 return false;
1930 }
1931
Brandon Jonesd1049182018-03-28 10:02:20 -07001932 GLsizei numParams = 0;
1933
1934 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001935 {
1936 return false;
1937 }
1938
Brandon Jonesd1049182018-03-28 10:02:20 -07001939 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001940 {
1941 return false;
1942 }
1943
Brandon Jonesd1049182018-03-28 10:02:20 -07001944 SetRobustLengthParam(length, numParams);
1945
Geoff Lang2186c382016-10-14 10:54:54 -04001946 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001947}
1948
1949bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1950{
1951 if (!context->getExtensions().disjointTimerQuery)
1952 {
Jamie Madille0472f32018-11-27 16:32:45 -05001953 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001954 return false;
1955 }
Geoff Lang2186c382016-10-14 10:54:54 -04001956 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1957}
1958
1959bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1960 GLuint id,
1961 GLenum pname,
1962 GLsizei bufSize,
1963 GLsizei *length,
1964 GLint64 *params)
1965{
1966 if (!context->getExtensions().disjointTimerQuery)
1967 {
Jamie Madille0472f32018-11-27 16:32:45 -05001968 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001969 return false;
1970 }
1971
1972 if (!ValidateRobustEntryPoint(context, bufSize))
1973 {
1974 return false;
1975 }
1976
Brandon Jonesd1049182018-03-28 10:02:20 -07001977 GLsizei numParams = 0;
1978
1979 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001980 {
1981 return false;
1982 }
1983
Brandon Jonesd1049182018-03-28 10:02:20 -07001984 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001985 {
1986 return false;
1987 }
1988
Brandon Jonesd1049182018-03-28 10:02:20 -07001989 SetRobustLengthParam(length, numParams);
1990
Geoff Lang2186c382016-10-14 10:54:54 -04001991 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001992}
1993
1994bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
1995{
1996 if (!context->getExtensions().disjointTimerQuery)
1997 {
Jamie Madille0472f32018-11-27 16:32:45 -05001998 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001999 return false;
2000 }
Geoff Lang2186c382016-10-14 10:54:54 -04002001 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
2002}
2003
2004bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
2005 GLuint id,
2006 GLenum pname,
2007 GLsizei bufSize,
2008 GLsizei *length,
2009 GLuint64 *params)
2010{
2011 if (!context->getExtensions().disjointTimerQuery)
2012 {
Jamie Madille0472f32018-11-27 16:32:45 -05002013 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002014 return false;
2015 }
2016
2017 if (!ValidateRobustEntryPoint(context, bufSize))
2018 {
2019 return false;
2020 }
2021
Brandon Jonesd1049182018-03-28 10:02:20 -07002022 GLsizei numParams = 0;
2023
2024 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002025 {
2026 return false;
2027 }
2028
Brandon Jonesd1049182018-03-28 10:02:20 -07002029 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002030 {
2031 return false;
2032 }
2033
Brandon Jonesd1049182018-03-28 10:02:20 -07002034 SetRobustLengthParam(length, numParams);
2035
Geoff Lang2186c382016-10-14 10:54:54 -04002036 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002037}
2038
Jamie Madill5b772312018-03-08 20:28:32 -05002039bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002040 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002041 GLint location,
2042 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002043 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002044{
Jiajia Qin5451d532017-11-16 17:16:34 +08002045 // TODO(Jiajia): Add image uniform check in future.
2046 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002047 {
Jamie Madille0472f32018-11-27 16:32:45 -05002048 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002049 return false;
2050 }
2051
Jiajia Qin5451d532017-11-16 17:16:34 +08002052 if (!program)
2053 {
Jamie Madille0472f32018-11-27 16:32:45 -05002054 context->validationError(GL_INVALID_OPERATION, kInvalidProgramName);
Jiajia Qin5451d532017-11-16 17:16:34 +08002055 return false;
2056 }
2057
2058 if (!program->isLinked())
2059 {
Jamie Madille0472f32018-11-27 16:32:45 -05002060 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiajia Qin5451d532017-11-16 17:16:34 +08002061 return false;
2062 }
2063
2064 if (location == -1)
2065 {
2066 // Silently ignore the uniform command
2067 return false;
2068 }
2069
2070 const auto &uniformLocations = program->getUniformLocations();
2071 size_t castedLocation = static_cast<size_t>(location);
2072 if (castedLocation >= uniformLocations.size())
2073 {
Jamie Madille0472f32018-11-27 16:32:45 -05002074 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002075 return false;
2076 }
2077
2078 const auto &uniformLocation = uniformLocations[castedLocation];
2079 if (uniformLocation.ignored)
2080 {
2081 // Silently ignore the uniform command
2082 return false;
2083 }
2084
2085 if (!uniformLocation.used())
2086 {
Jamie Madille0472f32018-11-27 16:32:45 -05002087 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002088 return false;
2089 }
2090
2091 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2092
2093 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002094 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002095 {
Jamie Madille0472f32018-11-27 16:32:45 -05002096 context->validationError(GL_INVALID_OPERATION, kInvalidUniformCount);
Jiajia Qin5451d532017-11-16 17:16:34 +08002097 return false;
2098 }
2099
2100 *uniformOut = &uniform;
2101 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002102}
2103
Jamie Madill5b772312018-03-08 20:28:32 -05002104bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002105 GLenum uniformType,
2106 GLsizei count,
2107 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002108{
Jiajia Qin5451d532017-11-16 17:16:34 +08002109 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2110 // It is compatible with INT or BOOL.
2111 // Do these cheap tests first, for a little extra speed.
2112 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002113 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002114 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002115 }
2116
Jiajia Qin5451d532017-11-16 17:16:34 +08002117 if (IsSamplerType(uniformType))
2118 {
2119 // Check that the values are in range.
2120 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2121 for (GLsizei i = 0; i < count; ++i)
2122 {
2123 if (value[i] < 0 || value[i] >= max)
2124 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002125 context->validationError(GL_INVALID_VALUE, kSamplerUniformValueOutOfRange);
Jiajia Qin5451d532017-11-16 17:16:34 +08002126 return false;
2127 }
2128 }
2129 return true;
2130 }
2131
Jamie Madillc3e37312018-11-30 15:25:39 -05002132 context->validationError(GL_INVALID_OPERATION, kUniformTypeMismatch);
Jiajia Qin5451d532017-11-16 17:16:34 +08002133 return false;
2134}
2135
Jamie Madill5b772312018-03-08 20:28:32 -05002136bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002137{
2138 // Check that the value type is compatible with uniform type.
2139 if (valueType == uniformType)
2140 {
2141 return true;
2142 }
2143
Jamie Madillc3e37312018-11-30 15:25:39 -05002144 context->validationError(GL_INVALID_OPERATION, kUniformTypeMismatch);
Jiajia Qin5451d532017-11-16 17:16:34 +08002145 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002146}
2147
Jamie Madill5b772312018-03-08 20:28:32 -05002148bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002149{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002150 const LinkedUniform *uniform = nullptr;
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002151 Program *programObject = context->getState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002152 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2153 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002154}
2155
Jamie Madill5b772312018-03-08 20:28:32 -05002156bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002157{
2158 const LinkedUniform *uniform = nullptr;
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002159 Program *programObject = context->getState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002160 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2161 ValidateUniform1ivValue(context, uniform->type, count, value);
2162}
2163
Jamie Madill5b772312018-03-08 20:28:32 -05002164bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002165 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002166 GLint location,
2167 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002168 GLboolean transpose)
2169{
Geoff Lang92019432017-11-20 13:09:34 -05002170 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002171 {
Jamie Madille0472f32018-11-27 16:32:45 -05002172 context->validationError(GL_INVALID_VALUE, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04002173 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002174 }
2175
Jamie Madill62d31cb2015-09-11 13:25:51 -04002176 const LinkedUniform *uniform = nullptr;
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002177 Program *programObject = context->getState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002178 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2179 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002180}
2181
Jamie Madill5b772312018-03-08 20:28:32 -05002182bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002183{
2184 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2185 {
Jamie Madille0472f32018-11-27 16:32:45 -05002186 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langb1196682014-07-23 13:47:29 -04002187 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002188 }
2189
Jamie Madill0af26e12015-03-05 19:54:33 -05002190 const Caps &caps = context->getCaps();
2191
Jamie Madill893ab082014-05-16 16:56:10 -04002192 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2193 {
2194 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2195
Jamie Madill0af26e12015-03-05 19:54:33 -05002196 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002197 {
Jamie Madille0472f32018-11-27 16:32:45 -05002198 context->validationError(GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
Geoff Langb1196682014-07-23 13:47:29 -04002199 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002200 }
2201 }
2202
2203 switch (pname)
2204 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002205 case GL_TEXTURE_BINDING_2D:
2206 case GL_TEXTURE_BINDING_CUBE_MAP:
2207 case GL_TEXTURE_BINDING_3D:
2208 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002209 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002210 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002211 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002212 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002213 {
Jamie Madille0472f32018-11-27 16:32:45 -05002214 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03002215 return false;
2216 }
2217 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002218 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2219 if (!context->getExtensions().textureRectangle)
2220 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002221 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002222 return false;
2223 }
2224 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002225 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2226 if (!context->getExtensions().eglStreamConsumerExternal &&
2227 !context->getExtensions().eglImageExternal)
2228 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002229 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08002230 return false;
2231 }
2232 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002233
He Yunchaoced53ae2016-11-29 15:00:51 +08002234 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2235 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002236 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002237 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
Jamie Madille98b1b52018-03-08 09:47:23 -05002238 ASSERT(readFramebuffer);
2239
Jamie Madill610640f2018-11-21 17:28:41 -05002240 if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002241 {
Geoff Langb1196682014-07-23 13:47:29 -04002242 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002243 }
2244
Jamie Madille98b1b52018-03-08 09:47:23 -05002245 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002246 {
Jamie Madille0472f32018-11-27 16:32:45 -05002247 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002248 return false;
2249 }
2250
Jamie Madille98b1b52018-03-08 09:47:23 -05002251 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002252 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002253 {
Jamie Madille0472f32018-11-27 16:32:45 -05002254 context->validationError(GL_INVALID_OPERATION, kReadBufferNotAttached);
Geoff Langb1196682014-07-23 13:47:29 -04002255 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002256 }
2257 }
2258 break;
2259
He Yunchaoced53ae2016-11-29 15:00:51 +08002260 default:
2261 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002262 }
2263
2264 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002265 if (*numParams == 0)
2266 {
2267 return false;
2268 }
2269
2270 return true;
2271}
2272
Brandon Jonesd1049182018-03-28 10:02:20 -07002273bool ValidateGetBooleanvRobustANGLE(Context *context,
2274 GLenum pname,
2275 GLsizei bufSize,
2276 GLsizei *length,
2277 GLboolean *params)
2278{
2279 GLenum nativeType;
2280 unsigned int numParams = 0;
2281
2282 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2283 {
2284 return false;
2285 }
2286
2287 SetRobustLengthParam(length, numParams);
2288
2289 return true;
2290}
2291
2292bool ValidateGetFloatvRobustANGLE(Context *context,
2293 GLenum pname,
2294 GLsizei bufSize,
2295 GLsizei *length,
2296 GLfloat *params)
2297{
2298 GLenum nativeType;
2299 unsigned int numParams = 0;
2300
2301 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2302 {
2303 return false;
2304 }
2305
2306 SetRobustLengthParam(length, numParams);
2307
2308 return true;
2309}
2310
2311bool ValidateGetIntegervRobustANGLE(Context *context,
2312 GLenum pname,
2313 GLsizei bufSize,
2314 GLsizei *length,
2315 GLint *data)
2316{
2317 GLenum nativeType;
2318 unsigned int numParams = 0;
2319
2320 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2321 {
2322 return false;
2323 }
2324
2325 SetRobustLengthParam(length, numParams);
2326
2327 return true;
2328}
2329
2330bool ValidateGetInteger64vRobustANGLE(Context *context,
2331 GLenum pname,
2332 GLsizei bufSize,
2333 GLsizei *length,
2334 GLint64 *data)
2335{
2336 GLenum nativeType;
2337 unsigned int numParams = 0;
2338
2339 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2340 {
2341 return false;
2342 }
2343
2344 if (nativeType == GL_INT_64_ANGLEX)
2345 {
2346 CastStateValues(context, nativeType, pname, numParams, data);
2347 return false;
2348 }
2349
2350 SetRobustLengthParam(length, numParams);
2351 return true;
2352}
2353
Jamie Madill5b772312018-03-08 20:28:32 -05002354bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002355 GLenum pname,
2356 GLsizei bufSize,
2357 GLenum *nativeType,
2358 unsigned int *numParams)
2359{
2360 if (!ValidateRobustEntryPoint(context, bufSize))
2361 {
2362 return false;
2363 }
2364
2365 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2366 {
2367 return false;
2368 }
2369
2370 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002371 {
2372 return false;
2373 }
2374
2375 return true;
2376}
2377
Jamie Madill5b772312018-03-08 20:28:32 -05002378bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002379 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002380 GLint level,
2381 GLenum internalformat,
2382 bool isSubImage,
2383 GLint xoffset,
2384 GLint yoffset,
2385 GLint zoffset,
2386 GLint x,
2387 GLint y,
2388 GLsizei width,
2389 GLsizei height,
2390 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002391 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002392{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002393 TextureType texType = TextureTargetToType(target);
2394
Brandon Jones6cad5662017-06-14 13:25:13 -07002395 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002396 {
Jamie Madille0472f32018-11-27 16:32:45 -05002397 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07002398 return false;
2399 }
2400
2401 if (width < 0 || height < 0)
2402 {
Jamie Madille0472f32018-11-27 16:32:45 -05002403 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002404 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002405 }
2406
He Yunchaoced53ae2016-11-29 15:00:51 +08002407 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2408 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002409 {
Jamie Madille0472f32018-11-27 16:32:45 -05002410 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002411 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002412 }
2413
2414 if (border != 0)
2415 {
Jamie Madille0472f32018-11-27 16:32:45 -05002416 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002417 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002418 }
2419
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002420 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002421 {
Jamie Madille0472f32018-11-27 16:32:45 -05002422 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002423 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002424 }
2425
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002426 const State &state = context->getState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002427 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002428 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002429 {
Geoff Langb1196682014-07-23 13:47:29 -04002430 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002431 }
2432
Jamie Madille98b1b52018-03-08 09:47:23 -05002433 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002434 {
Geoff Langb1196682014-07-23 13:47:29 -04002435 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002436 }
2437
Martin Radev138064f2016-07-15 12:03:41 +03002438 if (readFramebuffer->getReadBufferState() == GL_NONE)
2439 {
Jamie Madille0472f32018-11-27 16:32:45 -05002440 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002441 return false;
2442 }
2443
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002444 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2445 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002446 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002447 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002448 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2449 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002450 {
Jamie Madille0472f32018-11-27 16:32:45 -05002451 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002452 return false;
2453 }
2454
Martin Radev04e2c3b2017-07-27 16:54:35 +03002455 // ANGLE_multiview spec, Revision 1:
2456 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2457 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002458 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2459 // framebuffer is more than one.
2460 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002461 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002462 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
Martin Radev04e2c3b2017-07-27 16:54:35 +03002463 return false;
2464 }
2465
Jamie Madill43da7c42018-08-01 11:34:49 -04002466 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002467
Geoff Langaae65a42014-05-26 12:43:44 -04002468 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002469 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002470 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002471 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002472 maxDimension = caps.max2DTextureSize;
2473 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002474
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002475 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002476 maxDimension = caps.maxCubeMapTextureSize;
2477 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002478
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002479 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002480 maxDimension = caps.maxRectangleTextureSize;
2481 break;
2482
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002483 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002484 maxDimension = caps.max2DTextureSize;
2485 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002486
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002487 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002488 maxDimension = caps.max3DTextureSize;
2489 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002490
He Yunchaoced53ae2016-11-29 15:00:51 +08002491 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002492 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002493 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002494 }
2495
Jamie Madill43da7c42018-08-01 11:34:49 -04002496 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002497 if (!texture)
2498 {
Jamie Madille0472f32018-11-27 16:32:45 -05002499 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002500 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002501 }
2502
Geoff Lang69cce582015-09-17 13:20:36 -04002503 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002504 {
Jamie Madille0472f32018-11-27 16:32:45 -05002505 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002506 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002507 }
2508
Jamie Madill43da7c42018-08-01 11:34:49 -04002509 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002510 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002511 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002512
Geoff Lang966c9402017-04-18 12:38:27 -04002513 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002514 {
Jamie Madille0472f32018-11-27 16:32:45 -05002515 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Langa9be0dc2014-12-17 12:34:40 -05002516 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002517 }
2518
2519 if (isSubImage)
2520 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002521 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2522 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2523 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002524 {
Jamie Madille0472f32018-11-27 16:32:45 -05002525 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002526 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002527 }
2528 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002529 else
2530 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002531 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002532 {
Jamie Madille0472f32018-11-27 16:32:45 -05002533 context->validationError(GL_INVALID_VALUE, kCubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002534 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002535 }
2536
Geoff Langeb66a6e2016-10-31 13:06:12 -04002537 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002538 {
Jamie Madille0472f32018-11-27 16:32:45 -05002539 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002540 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002541 }
2542
2543 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002544 if (static_cast<int>(width) > maxLevelDimension ||
2545 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002546 {
Jamie Madille0472f32018-11-27 16:32:45 -05002547 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002548 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002549 }
2550 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002551
Jamie Madill0c8abca2016-07-22 20:21:26 -04002552 if (textureFormatOut)
2553 {
2554 *textureFormatOut = texture->getFormat(target, level);
2555 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002556
2557 // Detect texture copying feedback loops for WebGL.
2558 if (context->getExtensions().webglCompatibility)
2559 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002560 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002561 {
Jamie Madille0472f32018-11-27 16:32:45 -05002562 context->validationError(GL_INVALID_OPERATION, kFeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002563 return false;
2564 }
2565 }
2566
Jamie Madill560a8d82014-05-21 13:06:20 -04002567 return true;
2568}
2569
Jamie Madillb42162f2018-08-20 12:58:37 -04002570// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2571// completeness check.
2572const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002573{
2574 const Extensions &extensions = context->getExtensions();
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002575 const State &state = context->getState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002576
2577 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2578 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2579 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002580 VertexArray *vertexArray = state.getVertexArray();
2581 ASSERT(vertexArray);
2582
2583 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002584 {
Jamie Madille0472f32018-11-27 16:32:45 -05002585 return kBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002586 }
2587
2588 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2589 // Section 6.10 of the WebGL 1.0 spec.
2590 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002591 ASSERT(framebuffer);
2592
Jamie Madille7d80f32018-08-08 15:49:23 -04002593 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2594 {
2595 ASSERT(framebuffer);
2596 const FramebufferAttachment *dsAttachment =
2597 framebuffer->getStencilOrDepthStencilAttachment();
2598 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2599 ASSERT(stencilBits <= 8);
2600
2601 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2602 if (depthStencilState.stencilTest && stencilBits > 0)
2603 {
2604 GLuint maxStencilValue = (1 << stencilBits) - 1;
2605
2606 bool differentRefs =
2607 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2608 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2609 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2610 (depthStencilState.stencilBackWritemask & maxStencilValue);
2611 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2612 (depthStencilState.stencilBackMask & maxStencilValue);
2613
2614 if (differentRefs || differentWritemasks || differentMasks)
2615 {
2616 if (!extensions.webglCompatibility)
2617 {
2618 WARN() << "This ANGLE implementation does not support separate front/back "
2619 "stencil writemasks, reference values, or stencil mask values.";
2620 }
Jamie Madille0472f32018-11-27 16:32:45 -05002621 return kStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002622 }
2623 }
2624 }
2625
2626 if (!framebuffer->isComplete(context))
2627 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002628 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
Jamie Madille0472f32018-11-27 16:32:45 -05002629 return kDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002630 }
2631
2632 if (context->getStateCache().hasAnyEnabledClientAttrib())
2633 {
2634 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2635 {
2636 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2637 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2638 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2639 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madille0472f32018-11-27 16:32:45 -05002640 return kVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002641 }
2642
2643 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2644 {
2645 // This is an application error that would normally result in a crash, but we catch it
2646 // and return an error
Jamie Madille0472f32018-11-27 16:32:45 -05002647 return kVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002648 }
2649 }
2650
2651 // If we are running GLES1, there is no current program.
2652 if (context->getClientVersion() >= Version(2, 0))
2653 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002654 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002655 if (!program)
2656 {
Jamie Madille0472f32018-11-27 16:32:45 -05002657 return kProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002658 }
2659
2660 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2661 // vertex shader stage or fragment shader stage is a undefined behaviour.
2662 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2663 // produce undefined result.
2664 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2665 !program->hasLinkedShaderStage(ShaderType::Fragment))
2666 {
Jamie Madille0472f32018-11-27 16:32:45 -05002667 return kNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002668 }
2669
2670 if (!program->validateSamplers(nullptr, context->getCaps()))
2671 {
Jamie Madille0472f32018-11-27 16:32:45 -05002672 return kTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002673 }
2674
2675 if (extensions.multiview)
2676 {
2677 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2678 const int framebufferNumViews = framebuffer->getNumViews();
2679 if (framebufferNumViews != programNumViews)
2680 {
Jamie Madille0472f32018-11-27 16:32:45 -05002681 return kMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002682 }
2683
2684 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2685 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
Jamie Madill3a256222018-12-08 09:56:39 -05002686 !transformFeedbackObject->isPaused() && framebufferNumViews > 1)
Jamie Madille7d80f32018-08-08 15:49:23 -04002687 {
Jamie Madille0472f32018-11-27 16:32:45 -05002688 return kMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002689 }
2690
2691 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2692 state.isQueryActive(QueryType::TimeElapsed))
2693 {
Jamie Madille0472f32018-11-27 16:32:45 -05002694 return kMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002695 }
2696 }
2697
2698 // Uniform buffer validation
2699 for (unsigned int uniformBlockIndex = 0;
2700 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2701 {
2702 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002703 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002704 const OffsetBindingPointer<Buffer> &uniformBuffer =
2705 state.getIndexedUniformBuffer(blockBinding);
2706
2707 if (uniformBuffer.get() == nullptr)
2708 {
2709 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002710 return kUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002711 }
2712
2713 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2714 if (uniformBufferSize < uniformBlock.dataSize)
2715 {
2716 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002717 return kUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002718 }
2719
2720 if (extensions.webglCompatibility &&
2721 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2722 {
Jamie Madille0472f32018-11-27 16:32:45 -05002723 return kUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002724 }
2725 }
2726
2727 // Do some additonal WebGL-specific validation
2728 if (extensions.webglCompatibility)
2729 {
2730 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2731 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2732 transformFeedbackObject->buffersBoundForOtherUse())
2733 {
Jamie Madille0472f32018-11-27 16:32:45 -05002734 return kTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002735 }
2736
2737 // Detect rendering feedback loops for WebGL.
2738 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2739 {
Jamie Madille0472f32018-11-27 16:32:45 -05002740 return kFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002741 }
2742
2743 // Detect that the vertex shader input types match the attribute types
2744 if (!ValidateVertexShaderAttributeTypeMatch(context))
2745 {
Jamie Madille0472f32018-11-27 16:32:45 -05002746 return kVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002747 }
2748
2749 // Detect that the color buffer types match the fragment shader output types
2750 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2751 {
Jamie Madille0472f32018-11-27 16:32:45 -05002752 return kDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002753 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002754
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002755 const VertexArray *vao = context->getState().getVertexArray();
Jamie Madill03cb5262018-08-08 15:49:24 -04002756 if (vao->hasTransformFeedbackBindingConflict(context))
2757 {
Jamie Madille0472f32018-11-27 16:32:45 -05002758 return kVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002759 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002760 }
2761 }
2762
Jamie Madillb42162f2018-08-20 12:58:37 -04002763 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002764}
2765
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002766void RecordDrawModeError(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002767{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002768 const State &state = context->getState();
Jamie Madill9b025062018-12-12 15:44:12 -05002769 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
2770 if (curTransformFeedback && curTransformFeedback->isActive() &&
2771 !curTransformFeedback->isPaused())
2772 {
2773 if (!ValidateTransformFeedbackPrimitiveMode(context,
2774 curTransformFeedback->getPrimitiveMode(), mode))
2775 {
2776 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002777 return;
Jamie Madill9b025062018-12-12 15:44:12 -05002778 }
2779 }
2780
Jiawei Shaofccebff2018-03-08 13:51:02 +08002781 const Extensions &extensions = context->getExtensions();
2782
Jamie Madill1aeb1312014-06-20 13:21:25 -04002783 switch (mode)
2784 {
Jamie Madill493f9572018-05-24 19:52:15 -04002785 case PrimitiveMode::Points:
2786 case PrimitiveMode::Lines:
2787 case PrimitiveMode::LineLoop:
2788 case PrimitiveMode::LineStrip:
2789 case PrimitiveMode::Triangles:
2790 case PrimitiveMode::TriangleStrip:
2791 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002792 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002793
Jamie Madill493f9572018-05-24 19:52:15 -04002794 case PrimitiveMode::LinesAdjacency:
2795 case PrimitiveMode::LineStripAdjacency:
2796 case PrimitiveMode::TrianglesAdjacency:
2797 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002798 if (!extensions.geometryShader)
2799 {
Jamie Madille0472f32018-11-27 16:32:45 -05002800 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002801 return;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002802 }
2803 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002804 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002805 context->validationError(GL_INVALID_ENUM, kInvalidDrawMode);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002806 return;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002807 }
2808
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002809 // If we are running GLES1, there is no current program.
2810 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002811 {
Jamie 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);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002823 return;
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002824 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002825 }
2826 }
2827
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002828 // An error should be recorded.
2829 UNREACHABLE();
Jamie Madillfd716582014-06-06 17:09:04 -04002830}
2831
He Yunchaoced53ae2016-11-29 15:00:51 +08002832bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002833 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002834 GLint first,
2835 GLsizei count,
2836 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002837{
Geoff Lang63c5a592017-09-27 14:08:16 -04002838 if (!context->getExtensions().instancedArrays)
2839 {
Jamie Madille0472f32018-11-27 16:32:45 -05002840 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002841 return false;
2842 }
2843
Corentin Wallez170efbf2017-05-02 13:45:01 -04002844 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002845 {
2846 return false;
2847 }
2848
Corentin Wallez0dc97812017-06-22 14:38:44 -04002849 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002850}
2851
Jamie Madill1e853262018-12-21 09:07:38 -05002852const char *ValidateDrawElementsStates(Context *context)
2853{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002854 const State &state = context->getState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002855
Jamie Madillae6ba9f2018-12-21 23:00:04 -05002856 if (context->getStateCache().isTransformFeedbackActiveUnpaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002857 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002858 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2859 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
Jamie Madill9b025062018-12-12 15:44:12 -05002860 if (!context->getExtensions().geometryShader)
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002861 {
2862 // It is an invalid operation to call DrawElements, DrawRangeElements or
2863 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
2864 // 86)
Jamie Madill1e853262018-12-21 09:07:38 -05002865 return kUnsupportedDrawModeForTransformFeedback;
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002866 }
Jamie Madill250d33f2014-06-06 17:09:03 -04002867 }
2868
Jamie Madillf5c88e72018-12-08 09:56:38 -05002869 const VertexArray *vao = state.getVertexArray();
2870 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
2871
2872 if (elementArrayBuffer)
2873 {
2874 if (context->getExtensions().webglCompatibility)
2875 {
2876 if (elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
2877 {
Jamie Madill1e853262018-12-21 09:07:38 -05002878 return kElementArrayBufferBoundForTransformFeedback;
Jamie Madillf5c88e72018-12-08 09:56:38 -05002879 }
2880 }
2881 else if (elementArrayBuffer->isMapped())
2882 {
2883 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
2884 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the
2885 // WebGL 2.0 API. https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madill1e853262018-12-21 09:07:38 -05002886 return kBufferMapped;
Jamie Madillf5c88e72018-12-08 09:56:38 -05002887 }
2888 }
2889 else
2890 {
2891 // [WebGL 1.0] Section 6.2 No Client Side Arrays
2892 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
2893 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002894 if (!context->getState().areClientArraysEnabled() ||
Jamie Madillf5c88e72018-12-08 09:56:38 -05002895 context->getExtensions().webglCompatibility)
2896 {
Jamie Madill1e853262018-12-21 09:07:38 -05002897 return kMustHaveElementArrayBinding;
Jamie Madillf5c88e72018-12-08 09:56:38 -05002898 }
2899 }
2900
Jamie Madill1e853262018-12-21 09:07:38 -05002901 return nullptr;
Jiajia Qind9671222016-11-29 16:30:31 +08002902}
2903
Jamie Madill5b772312018-03-08 20:28:32 -05002904bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002905 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002906 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05002907 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04002908 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002909 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04002910{
Corentin Wallez0dc97812017-06-22 14:38:44 -04002911 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04002912}
2913
Geoff Lang3edfe032015-09-04 16:38:24 -04002914bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002915 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04002916 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05002917 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04002918 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002919 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002920{
Geoff Lang63c5a592017-09-27 14:08:16 -04002921 if (!context->getExtensions().instancedArrays)
2922 {
Jamie Madille0472f32018-11-27 16:32:45 -05002923 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002924 return false;
2925 }
2926
Corentin Wallez170efbf2017-05-02 13:45:01 -04002927 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002928 {
2929 return false;
2930 }
2931
Corentin Wallez0dc97812017-06-22 14:38:44 -04002932 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002933}
2934
He Yunchaoced53ae2016-11-29 15:00:51 +08002935bool ValidateFramebufferTextureBase(Context *context,
2936 GLenum target,
2937 GLenum attachment,
2938 GLuint texture,
2939 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04002940{
Geoff Lange8afa902017-09-27 15:00:43 -04002941 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04002942 {
Jamie Madille0472f32018-11-27 16:32:45 -05002943 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04002944 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002945 }
2946
2947 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04002948 {
2949 return false;
2950 }
2951
Jamie Madill55ec3b12014-07-03 10:38:57 -04002952 if (texture != 0)
2953 {
Jamie Madill43da7c42018-08-01 11:34:49 -04002954 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04002955
Luc Ferronadcf0ae2018-01-24 08:27:37 -05002956 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04002957 {
Jamie Madille0472f32018-11-27 16:32:45 -05002958 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04002959 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002960 }
2961
2962 if (level < 0)
2963 {
Jamie Madille0472f32018-11-27 16:32:45 -05002964 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002965 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002966 }
2967 }
2968
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002969 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04002970 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04002971
Jamie Madill84115c92015-04-23 15:00:07 -04002972 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04002973 {
Jamie Madille0472f32018-11-27 16:32:45 -05002974 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04002975 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002976 }
2977
2978 return true;
2979}
2980
Geoff Langb1196682014-07-23 13:47:29 -04002981bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04002982{
2983 if (program == 0)
2984 {
Jamie Madille0472f32018-11-27 16:32:45 -05002985 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04002986 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04002987 }
2988
Jamie Madill43da7c42018-08-01 11:34:49 -04002989 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07002990 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05002991 {
2992 return false;
2993 }
2994
Jamie Madill0063c512014-08-25 15:47:53 -04002995 if (!programObject || !programObject->isLinked())
2996 {
Jamie Madille0472f32018-11-27 16:32:45 -05002997 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04002998 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04002999 }
3000
Geoff Lang7dd2e102014-11-10 15:19:26 -05003001 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003002 {
Jamie Madille0472f32018-11-27 16:32:45 -05003003 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003004 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003005 }
3006
Jamie Madill0063c512014-08-25 15:47:53 -04003007 return true;
3008}
3009
Geoff Langf41d0ee2016-10-07 13:04:23 -04003010static bool ValidateSizedGetUniform(Context *context,
3011 GLuint program,
3012 GLint location,
3013 GLsizei bufSize,
3014 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003015{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003016 if (length)
3017 {
3018 *length = 0;
3019 }
3020
Jamie Madill78f41802014-08-25 15:47:55 -04003021 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003022 {
Jamie Madill78f41802014-08-25 15:47:55 -04003023 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003024 }
3025
Geoff Langf41d0ee2016-10-07 13:04:23 -04003026 if (bufSize < 0)
3027 {
Jamie Madille0472f32018-11-27 16:32:45 -05003028 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003029 return false;
3030 }
3031
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003032 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003033 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003034
Jamie Madill78f41802014-08-25 15:47:55 -04003035 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003036 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003037 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003038 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003039 {
Jamie Madille0472f32018-11-27 16:32:45 -05003040 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003041 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003042 }
3043
Geoff Langf41d0ee2016-10-07 13:04:23 -04003044 if (length)
3045 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003046 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003047 }
3048
Jamie Madill0063c512014-08-25 15:47:53 -04003049 return true;
3050}
3051
He Yunchaoced53ae2016-11-29 15:00:51 +08003052bool ValidateGetnUniformfvEXT(Context *context,
3053 GLuint program,
3054 GLint location,
3055 GLsizei bufSize,
3056 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003057{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003058 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003059}
3060
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003061bool ValidateGetnUniformfvRobustANGLE(Context *context,
3062 GLuint program,
3063 GLint location,
3064 GLsizei bufSize,
3065 GLsizei *length,
3066 GLfloat *params)
3067{
3068 UNIMPLEMENTED();
3069 return false;
3070}
3071
He Yunchaoced53ae2016-11-29 15:00:51 +08003072bool ValidateGetnUniformivEXT(Context *context,
3073 GLuint program,
3074 GLint location,
3075 GLsizei bufSize,
3076 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003077{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003078 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3079}
3080
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003081bool ValidateGetnUniformivRobustANGLE(Context *context,
3082 GLuint program,
3083 GLint location,
3084 GLsizei bufSize,
3085 GLsizei *length,
3086 GLint *params)
3087{
3088 UNIMPLEMENTED();
3089 return false;
3090}
3091
3092bool ValidateGetnUniformuivRobustANGLE(Context *context,
3093 GLuint program,
3094 GLint location,
3095 GLsizei bufSize,
3096 GLsizei *length,
3097 GLuint *params)
3098{
3099 UNIMPLEMENTED();
3100 return false;
3101}
3102
Geoff Langf41d0ee2016-10-07 13:04:23 -04003103bool ValidateGetUniformfvRobustANGLE(Context *context,
3104 GLuint program,
3105 GLint location,
3106 GLsizei bufSize,
3107 GLsizei *length,
3108 GLfloat *params)
3109{
3110 if (!ValidateRobustEntryPoint(context, bufSize))
3111 {
3112 return false;
3113 }
3114
Brandon Jonesd1049182018-03-28 10:02:20 -07003115 GLsizei writeLength = 0;
3116
Geoff Langf41d0ee2016-10-07 13:04:23 -04003117 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003118 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3119 {
3120 return false;
3121 }
3122
3123 SetRobustLengthParam(length, writeLength);
3124
3125 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003126}
3127
3128bool ValidateGetUniformivRobustANGLE(Context *context,
3129 GLuint program,
3130 GLint location,
3131 GLsizei bufSize,
3132 GLsizei *length,
3133 GLint *params)
3134{
3135 if (!ValidateRobustEntryPoint(context, bufSize))
3136 {
3137 return false;
3138 }
3139
Brandon Jonesd1049182018-03-28 10:02:20 -07003140 GLsizei writeLength = 0;
3141
Geoff Langf41d0ee2016-10-07 13:04:23 -04003142 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003143 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3144 {
3145 return false;
3146 }
3147
3148 SetRobustLengthParam(length, writeLength);
3149
3150 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003151}
3152
3153bool ValidateGetUniformuivRobustANGLE(Context *context,
3154 GLuint program,
3155 GLint location,
3156 GLsizei bufSize,
3157 GLsizei *length,
3158 GLuint *params)
3159{
3160 if (!ValidateRobustEntryPoint(context, bufSize))
3161 {
3162 return false;
3163 }
3164
3165 if (context->getClientMajorVersion() < 3)
3166 {
Jamie Madille0472f32018-11-27 16:32:45 -05003167 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003168 return false;
3169 }
3170
Brandon Jonesd1049182018-03-28 10:02:20 -07003171 GLsizei writeLength = 0;
3172
Geoff Langf41d0ee2016-10-07 13:04:23 -04003173 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003174 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3175 {
3176 return false;
3177 }
3178
3179 SetRobustLengthParam(length, writeLength);
3180
3181 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003182}
3183
He Yunchaoced53ae2016-11-29 15:00:51 +08003184bool ValidateDiscardFramebufferBase(Context *context,
3185 GLenum target,
3186 GLsizei numAttachments,
3187 const GLenum *attachments,
3188 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003189{
3190 if (numAttachments < 0)
3191 {
Jamie Madille0472f32018-11-27 16:32:45 -05003192 context->validationError(GL_INVALID_VALUE, kNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003193 return false;
3194 }
3195
3196 for (GLsizei i = 0; i < numAttachments; ++i)
3197 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003198 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003199 {
3200 if (defaultFramebuffer)
3201 {
Jamie Madille0472f32018-11-27 16:32:45 -05003202 context->validationError(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003203 return false;
3204 }
3205
3206 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3207 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003208 context->validationError(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003209 return false;
3210 }
3211 }
3212 else
3213 {
3214 switch (attachments[i])
3215 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003216 case GL_DEPTH_ATTACHMENT:
3217 case GL_STENCIL_ATTACHMENT:
3218 case GL_DEPTH_STENCIL_ATTACHMENT:
3219 if (defaultFramebuffer)
3220 {
Jamie Madill610640f2018-11-21 17:28:41 -05003221 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003222 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003223 return false;
3224 }
3225 break;
3226 case GL_COLOR:
3227 case GL_DEPTH:
3228 case GL_STENCIL:
3229 if (!defaultFramebuffer)
3230 {
Jamie Madill610640f2018-11-21 17:28:41 -05003231 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003232 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003233 return false;
3234 }
3235 break;
3236 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003237 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003238 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003239 }
3240 }
3241 }
3242
3243 return true;
3244}
3245
Austin Kinross6ee1e782015-05-29 17:05:37 -07003246bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3247{
Jamie Madill007530e2017-12-28 14:27:04 -05003248 if (!context->getExtensions().debugMarker)
3249 {
3250 // The debug marker calls should not set error state
3251 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003252 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003253 return false;
3254 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003255
Jamie Madill007530e2017-12-28 14:27:04 -05003256 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003257 if (length < 0)
3258 {
3259 return false;
3260 }
3261
3262 if (marker == nullptr)
3263 {
3264 return false;
3265 }
3266
3267 return true;
3268}
3269
3270bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3271{
Jamie Madill007530e2017-12-28 14:27:04 -05003272 if (!context->getExtensions().debugMarker)
3273 {
3274 // The debug marker calls should not set error state
3275 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003276 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003277 return false;
3278 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003279
Jamie Madill007530e2017-12-28 14:27:04 -05003280 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003281 if (length < 0)
3282 {
3283 return false;
3284 }
3285
3286 if (length > 0 && marker == nullptr)
3287 {
3288 return false;
3289 }
3290
3291 return true;
3292}
3293
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003294bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003295{
Geoff Langa8406172015-07-21 16:53:39 -04003296 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3297 {
Jamie Madille0472f32018-11-27 16:32:45 -05003298 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003299 return false;
3300 }
3301
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003302 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003303 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003304 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003305 if (!context->getExtensions().eglImage)
3306 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003307 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb66a9092016-05-16 15:59:14 -04003308 }
3309 break;
3310
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003311 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003312 if (!context->getExtensions().eglImageExternal)
3313 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003314 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb66a9092016-05-16 15:59:14 -04003315 }
Geoff Langa8406172015-07-21 16:53:39 -04003316 break;
3317
3318 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003319 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003320 return false;
3321 }
3322
Rafael Cintron05a449a2018-06-20 18:08:04 -07003323 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003324
Jamie Madill61e16b42017-06-19 11:13:23 -04003325 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003326 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003327 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003328 context->validationError(GL_INVALID_VALUE, kInvalidEGLImage);
Geoff Langa8406172015-07-21 16:53:39 -04003329 return false;
3330 }
3331
Jamie Madill007530e2017-12-28 14:27:04 -05003332 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003333 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003334 context->validationError(GL_INVALID_OPERATION, kEGLImageCannotCreate2DMultisampled);
Geoff Langa8406172015-07-21 16:53:39 -04003335 return false;
3336 }
3337
Yuly Novikov2eb54072018-08-22 16:41:26 -04003338 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003339 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003340 context->validationError(GL_INVALID_OPERATION, kEGLImageTextureFormatNotSupported);
Geoff Langa8406172015-07-21 16:53:39 -04003341 return false;
3342 }
3343
Geoff Langdcab33b2015-07-21 13:03:16 -04003344 return true;
3345}
3346
3347bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003348 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003349 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003350{
Geoff Langa8406172015-07-21 16:53:39 -04003351 if (!context->getExtensions().eglImage)
3352 {
Jamie Madille0472f32018-11-27 16:32:45 -05003353 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003354 return false;
3355 }
3356
3357 switch (target)
3358 {
3359 case GL_RENDERBUFFER:
3360 break;
3361
3362 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003363 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003364 return false;
3365 }
3366
Rafael Cintron05a449a2018-06-20 18:08:04 -07003367 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003368
Jamie Madill61e16b42017-06-19 11:13:23 -04003369 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003370 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003371 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003372 context->validationError(GL_INVALID_VALUE, kInvalidEGLImage);
Geoff Langa8406172015-07-21 16:53:39 -04003373 return false;
3374 }
3375
Yuly Novikov2eb54072018-08-22 16:41:26 -04003376 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003377 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003378 context->validationError(GL_INVALID_OPERATION, kEGLImageRenderbufferFormatNotSupported);
Geoff Langa8406172015-07-21 16:53:39 -04003379 return false;
3380 }
3381
Geoff Langdcab33b2015-07-21 13:03:16 -04003382 return true;
3383}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003384
3385bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3386{
Geoff Lang36167ab2015-12-07 10:27:14 -05003387 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003388 {
3389 // The default VAO should always exist
3390 ASSERT(array != 0);
Jamie Madille0472f32018-11-27 16:32:45 -05003391 context->validationError(GL_INVALID_OPERATION, kInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003392 return false;
3393 }
3394
3395 return true;
3396}
3397
Geoff Langc5629752015-12-07 16:29:04 -05003398bool ValidateProgramBinaryBase(Context *context,
3399 GLuint program,
3400 GLenum binaryFormat,
3401 const void *binary,
3402 GLint length)
3403{
3404 Program *programObject = GetValidProgram(context, program);
3405 if (programObject == nullptr)
3406 {
3407 return false;
3408 }
3409
3410 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3411 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3412 programBinaryFormats.end())
3413 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003414 context->validationError(GL_INVALID_ENUM, kInvalidProgramBinaryFormat);
Geoff Langc5629752015-12-07 16:29:04 -05003415 return false;
3416 }
3417
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003418 if (context->hasActiveTransformFeedback(program))
3419 {
3420 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05003421 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackProgramBinary);
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003422 return false;
3423 }
3424
Geoff Langc5629752015-12-07 16:29:04 -05003425 return true;
3426}
3427
3428bool ValidateGetProgramBinaryBase(Context *context,
3429 GLuint program,
3430 GLsizei bufSize,
3431 GLsizei *length,
3432 GLenum *binaryFormat,
3433 void *binary)
3434{
3435 Program *programObject = GetValidProgram(context, program);
3436 if (programObject == nullptr)
3437 {
3438 return false;
3439 }
3440
3441 if (!programObject->isLinked())
3442 {
Jamie Madille0472f32018-11-27 16:32:45 -05003443 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003444 return false;
3445 }
3446
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003447 if (context->getCaps().programBinaryFormats.empty())
3448 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003449 context->validationError(GL_INVALID_OPERATION, kNoProgramBinaryFormats);
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003450 return false;
3451 }
3452
Geoff Langc5629752015-12-07 16:29:04 -05003453 return true;
3454}
Jamie Madillc29968b2016-01-20 11:17:23 -05003455
Jamie Madill5b772312018-03-08 20:28:32 -05003456bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003457{
3458 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003459 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003460 {
Jamie Madille0472f32018-11-27 16:32:45 -05003461 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003462 return false;
3463 }
3464 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3465 {
Jamie Madille0472f32018-11-27 16:32:45 -05003466 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003467 return false;
3468 }
3469
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003470 ASSERT(context->getState().getDrawFramebuffer());
3471 GLuint frameBufferId = context->getState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003472 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3473
3474 // This should come first before the check for the default frame buffer
3475 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3476 // rather than INVALID_OPERATION
3477 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3478 {
3479 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3480
3481 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003482 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3483 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003484 {
3485 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003486 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3487 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3488 // 3.1 is still a bit ambiguous about the error, but future specs are
3489 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madillc3e37312018-11-30 15:25:39 -05003490 context->validationError(GL_INVALID_ENUM, kInvalidDrawBuffer);
Olli Etuaho84c9f592016-03-09 14:37:25 +02003491 return false;
3492 }
3493 else if (bufs[colorAttachment] >= maxColorAttachment)
3494 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003495 context->validationError(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
Jamie Madillc29968b2016-01-20 11:17:23 -05003496 return false;
3497 }
3498 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3499 frameBufferId != 0)
3500 {
3501 // INVALID_OPERATION-GL is bound to buffer and ith argument
3502 // is not COLOR_ATTACHMENTi or NONE
Jamie Madillc3e37312018-11-30 15:25:39 -05003503 context->validationError(GL_INVALID_OPERATION, kInvalidDrawBufferValue);
Jamie Madillc29968b2016-01-20 11:17:23 -05003504 return false;
3505 }
3506 }
3507
3508 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3509 // and n is not 1 or bufs is bound to value other than BACK and NONE
3510 if (frameBufferId == 0)
3511 {
3512 if (n != 1)
3513 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003514 context->validationError(GL_INVALID_OPERATION, kInvalidDrawBufferCountForDefault);
Jamie Madillc29968b2016-01-20 11:17:23 -05003515 return false;
3516 }
3517
3518 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3519 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003520 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferInvalidDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003521 return false;
3522 }
3523 }
3524
3525 return true;
3526}
3527
Geoff Lang496c02d2016-10-20 11:38:11 -07003528bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003529 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003530 GLenum pname,
3531 GLsizei *length,
3532 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003533{
Geoff Lang496c02d2016-10-20 11:38:11 -07003534 if (length)
3535 {
3536 *length = 0;
3537 }
3538
Corentin Walleze4477002017-12-01 14:39:58 -05003539 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003540 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003541 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003542 return false;
3543 }
3544
Geoff Lang496c02d2016-10-20 11:38:11 -07003545 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003546 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003547 case GL_BUFFER_MAP_POINTER:
3548 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003549
Geoff Lang496c02d2016-10-20 11:38:11 -07003550 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003551 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003552 return false;
3553 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003554
3555 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3556 // target bound to zero generate an INVALID_OPERATION error."
3557 // GLES 3.1 section 6.6 explicitly specifies this error.
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003558 if (context->getState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003559 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003560 context->validationError(GL_INVALID_OPERATION, kBufferPointerNotAvailable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003561 return false;
3562 }
3563
Geoff Lang496c02d2016-10-20 11:38:11 -07003564 if (length)
3565 {
3566 *length = 1;
3567 }
3568
Olli Etuaho4f667482016-03-30 15:56:35 +03003569 return true;
3570}
3571
Corentin Wallez336129f2017-10-17 15:55:40 -04003572bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003573{
Corentin Walleze4477002017-12-01 14:39:58 -05003574 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003575 {
Jamie Madille0472f32018-11-27 16:32:45 -05003576 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003577 return false;
3578 }
3579
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003580 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003581
3582 if (buffer == nullptr || !buffer->isMapped())
3583 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003584 context->validationError(GL_INVALID_OPERATION, kBufferNotMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003585 return false;
3586 }
3587
3588 return true;
3589}
3590
3591bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003592 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003593 GLintptr offset,
3594 GLsizeiptr length,
3595 GLbitfield access)
3596{
Corentin Walleze4477002017-12-01 14:39:58 -05003597 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003598 {
Jamie Madille0472f32018-11-27 16:32:45 -05003599 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003600 return false;
3601 }
3602
Brandon Jones6cad5662017-06-14 13:25:13 -07003603 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003604 {
Jamie Madille0472f32018-11-27 16:32:45 -05003605 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003606 return false;
3607 }
3608
3609 if (length < 0)
3610 {
Jamie Madille0472f32018-11-27 16:32:45 -05003611 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003612 return false;
3613 }
3614
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003615 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003616
3617 if (!buffer)
3618 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003619 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003620 return false;
3621 }
3622
3623 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003624 CheckedNumeric<size_t> checkedOffset(offset);
3625 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003626
Jamie Madille2e406c2016-06-02 13:04:10 -04003627 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003628 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003629 context->validationError(GL_INVALID_VALUE, kMapOutOfRange);
Olli Etuaho4f667482016-03-30 15:56:35 +03003630 return false;
3631 }
3632
3633 // Check for invalid bits in the mask
3634 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3635 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3636 GL_MAP_UNSYNCHRONIZED_BIT;
3637
3638 if (access & ~(allAccessBits))
3639 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003640 context->validationError(GL_INVALID_VALUE, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003641 return false;
3642 }
3643
3644 if (length == 0)
3645 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003646 context->validationError(GL_INVALID_OPERATION, kLengthZero);
Olli Etuaho4f667482016-03-30 15:56:35 +03003647 return false;
3648 }
3649
3650 if (buffer->isMapped())
3651 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003652 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003653 return false;
3654 }
3655
3656 // Check for invalid bit combinations
3657 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3658 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003659 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite);
Olli Etuaho4f667482016-03-30 15:56:35 +03003660 return false;
3661 }
3662
3663 GLbitfield writeOnlyBits =
3664 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3665
3666 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3667 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003668 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsRead);
Olli Etuaho4f667482016-03-30 15:56:35 +03003669 return false;
3670 }
3671
3672 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3673 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003674 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsFlush);
Olli Etuaho4f667482016-03-30 15:56:35 +03003675 return false;
3676 }
Geoff Lang79f71042017-08-14 16:43:43 -04003677
3678 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003679}
3680
3681bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003682 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003683 GLintptr offset,
3684 GLsizeiptr length)
3685{
Brandon Jones6cad5662017-06-14 13:25:13 -07003686 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003687 {
Jamie Madille0472f32018-11-27 16:32:45 -05003688 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003689 return false;
3690 }
3691
3692 if (length < 0)
3693 {
Jamie Madille0472f32018-11-27 16:32:45 -05003694 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003695 return false;
3696 }
3697
Corentin Walleze4477002017-12-01 14:39:58 -05003698 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003699 {
Jamie Madille0472f32018-11-27 16:32:45 -05003700 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003701 return false;
3702 }
3703
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003704 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003705
3706 if (buffer == nullptr)
3707 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003708 context->validationError(GL_INVALID_OPERATION, kInvalidFlushZero);
Olli Etuaho4f667482016-03-30 15:56:35 +03003709 return false;
3710 }
3711
3712 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
3713 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003714 context->validationError(GL_INVALID_OPERATION, kInvalidFlushTarget);
Olli Etuaho4f667482016-03-30 15:56:35 +03003715 return false;
3716 }
3717
3718 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003719 CheckedNumeric<size_t> checkedOffset(offset);
3720 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003721
Jamie Madille2e406c2016-06-02 13:04:10 -04003722 if (!checkedSize.IsValid() ||
3723 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003724 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003725 context->validationError(GL_INVALID_VALUE, kInvalidFlushOutOfRange);
Olli Etuaho4f667482016-03-30 15:56:35 +03003726 return false;
3727 }
3728
3729 return true;
3730}
3731
Olli Etuaho41997e72016-03-10 13:38:39 +02003732bool ValidateGenOrDelete(Context *context, GLint n)
3733{
3734 if (n < 0)
3735 {
Jamie Madille0472f32018-11-27 16:32:45 -05003736 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02003737 return false;
3738 }
3739 return true;
3740}
3741
Jamie Madill5b772312018-03-08 20:28:32 -05003742bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04003743{
3744 if (!context->getExtensions().robustClientMemory)
3745 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003746 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langff5b2d52016-09-07 11:32:23 -04003747 return false;
3748 }
3749
3750 if (bufSize < 0)
3751 {
Jamie Madille0472f32018-11-27 16:32:45 -05003752 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04003753 return false;
3754 }
3755
3756 return true;
3757}
3758
Jamie Madill5b772312018-03-08 20:28:32 -05003759bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04003760{
3761 if (bufSize < numParams)
3762 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003763 context->validationError(GL_INVALID_OPERATION, kInsufficientParams);
Geoff Lang2e43dbb2016-10-14 12:27:35 -04003764 return false;
3765 }
3766
3767 return true;
3768}
3769
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08003770bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04003771 GLenum target,
3772 GLenum attachment,
3773 GLenum pname,
3774 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04003775{
Geoff Lange8afa902017-09-27 15:00:43 -04003776 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04003777 {
Jamie Madille0472f32018-11-27 16:32:45 -05003778 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04003779 return false;
3780 }
3781
3782 int clientVersion = context->getClientMajorVersion();
3783
3784 switch (pname)
3785 {
3786 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3787 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3788 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3789 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3790 break;
3791
Martin Radeve5285d22017-07-14 16:23:53 +03003792 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
3793 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
3794 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
3795 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
3796 if (clientVersion < 3 || !context->getExtensions().multiview)
3797 {
Jamie Madille0472f32018-11-27 16:32:45 -05003798 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03003799 return false;
3800 }
3801 break;
3802
Geoff Langff5b2d52016-09-07 11:32:23 -04003803 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
3804 if (clientVersion < 3 && !context->getExtensions().sRGB)
3805 {
Jamie Madille0472f32018-11-27 16:32:45 -05003806 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04003807 return false;
3808 }
3809 break;
3810
3811 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
3812 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
3813 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
3814 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
3815 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
3816 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
3817 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3818 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
3819 if (clientVersion < 3)
3820 {
Jamie Madille0472f32018-11-27 16:32:45 -05003821 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04003822 return false;
3823 }
3824 break;
3825
Jiawei Shaoa8802472018-05-28 11:17:47 +08003826 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
3827 if (!context->getExtensions().geometryShader)
3828 {
Jamie Madille0472f32018-11-27 16:32:45 -05003829 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08003830 return false;
3831 }
3832 break;
3833
Geoff Langff5b2d52016-09-07 11:32:23 -04003834 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003835 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04003836 return false;
3837 }
3838
3839 // Determine if the attachment is a valid enum
3840 switch (attachment)
3841 {
3842 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04003843 case GL_DEPTH:
3844 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04003845 if (clientVersion < 3)
3846 {
Jamie Madille0472f32018-11-27 16:32:45 -05003847 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003848 return false;
3849 }
3850 break;
3851
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08003852 case GL_DEPTH_STENCIL_ATTACHMENT:
3853 if (clientVersion < 3 && !context->isWebGL1())
3854 {
Jamie Madille0472f32018-11-27 16:32:45 -05003855 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08003856 return false;
3857 }
3858 break;
3859
Geoff Langfa125c92017-10-24 13:01:46 -04003860 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04003861 case GL_DEPTH_ATTACHMENT:
3862 case GL_STENCIL_ATTACHMENT:
3863 break;
3864
3865 default:
Geoff Langfa125c92017-10-24 13:01:46 -04003866 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
3867 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04003868 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
3869 {
Jamie Madille0472f32018-11-27 16:32:45 -05003870 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003871 return false;
3872 }
3873 break;
3874 }
3875
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003876 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
Geoff Langff5b2d52016-09-07 11:32:23 -04003877 ASSERT(framebuffer);
3878
3879 if (framebuffer->id() == 0)
3880 {
3881 if (clientVersion < 3)
3882 {
Jamie Madille0472f32018-11-27 16:32:45 -05003883 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04003884 return false;
3885 }
3886
3887 switch (attachment)
3888 {
3889 case GL_BACK:
3890 case GL_DEPTH:
3891 case GL_STENCIL:
3892 break;
3893
3894 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003895 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003896 return false;
3897 }
3898 }
3899 else
3900 {
3901 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
3902 {
3903 // Valid attachment query
3904 }
3905 else
3906 {
3907 switch (attachment)
3908 {
3909 case GL_DEPTH_ATTACHMENT:
3910 case GL_STENCIL_ATTACHMENT:
3911 break;
3912
3913 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08003914 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04003915 {
Jamie Madille0472f32018-11-27 16:32:45 -05003916 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003917 return false;
3918 }
3919 break;
3920
3921 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003922 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003923 return false;
3924 }
3925 }
3926 }
3927
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08003928 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003929 if (attachmentObject)
3930 {
3931 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
3932 attachmentObject->type() == GL_TEXTURE ||
3933 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
3934
3935 switch (pname)
3936 {
3937 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3938 if (attachmentObject->type() != GL_RENDERBUFFER &&
3939 attachmentObject->type() != GL_TEXTURE)
3940 {
Jamie Madille0472f32018-11-27 16:32:45 -05003941 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003942 return false;
3943 }
3944 break;
3945
3946 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3947 if (attachmentObject->type() != GL_TEXTURE)
3948 {
Jamie Madille0472f32018-11-27 16:32:45 -05003949 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003950 return false;
3951 }
3952 break;
3953
3954 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3955 if (attachmentObject->type() != GL_TEXTURE)
3956 {
Jamie Madille0472f32018-11-27 16:32:45 -05003957 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003958 return false;
3959 }
3960 break;
3961
3962 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3963 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
3964 {
Jamie Madille0472f32018-11-27 16:32:45 -05003965 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003966 return false;
3967 }
3968 break;
3969
3970 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
3971 if (attachmentObject->type() != GL_TEXTURE)
3972 {
Jamie Madille0472f32018-11-27 16:32:45 -05003973 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003974 return false;
3975 }
3976 break;
3977
3978 default:
3979 break;
3980 }
3981 }
3982 else
3983 {
3984 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3985 // is NONE, then querying any other pname will generate INVALID_ENUM.
3986
3987 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
3988 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3989 // INVALID_OPERATION for all other pnames
3990
3991 switch (pname)
3992 {
3993 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3994 break;
3995
3996 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3997 if (clientVersion < 3)
3998 {
Jamie Madill610640f2018-11-21 17:28:41 -05003999 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004000 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004001 return false;
4002 }
4003 break;
4004
4005 default:
4006 if (clientVersion < 3)
4007 {
Jamie Madill610640f2018-11-21 17:28:41 -05004008 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004009 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004010 return false;
4011 }
4012 else
4013 {
Jamie Madill610640f2018-11-21 17:28:41 -05004014 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05004015 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004016 return false;
4017 }
4018 }
4019 }
4020
Martin Radeve5285d22017-07-14 16:23:53 +03004021 if (numParams)
4022 {
4023 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4024 {
4025 // Only when the viewport offsets are queried we can have a varying number of output
4026 // parameters.
4027 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4028 *numParams = numViews * 2;
4029 }
4030 else
4031 {
4032 // For all other queries we can have only one output parameter.
4033 *numParams = 1;
4034 }
4035 }
4036
Geoff Langff5b2d52016-09-07 11:32:23 -04004037 return true;
4038}
4039
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004040bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004041 GLenum target,
4042 GLenum attachment,
4043 GLenum pname,
4044 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004045 GLsizei *length,
4046 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004047{
4048 if (!ValidateRobustEntryPoint(context, bufSize))
4049 {
4050 return false;
4051 }
4052
Brandon Jonesd1049182018-03-28 10:02:20 -07004053 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004054 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004055 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004056 {
4057 return false;
4058 }
4059
Brandon Jonesd1049182018-03-28 10:02:20 -07004060 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004061 {
4062 return false;
4063 }
4064
Brandon Jonesd1049182018-03-28 10:02:20 -07004065 SetRobustLengthParam(length, numParams);
4066
Geoff Langff5b2d52016-09-07 11:32:23 -04004067 return true;
4068}
4069
Jamie Madill5b772312018-03-08 20:28:32 -05004070bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004071 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004072 GLenum pname,
4073 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004074 GLsizei *length,
4075 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004076{
4077 if (!ValidateRobustEntryPoint(context, bufSize))
4078 {
4079 return false;
4080 }
4081
Brandon Jonesd1049182018-03-28 10:02:20 -07004082 GLsizei numParams = 0;
4083
4084 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004085 {
4086 return false;
4087 }
4088
Brandon Jonesd1049182018-03-28 10:02:20 -07004089 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004090 {
4091 return false;
4092 }
4093
Brandon Jonesd1049182018-03-28 10:02:20 -07004094 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004095 return true;
4096}
4097
Jamie Madill5b772312018-03-08 20:28:32 -05004098bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004099 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004100 GLenum pname,
4101 GLsizei bufSize,
4102 GLsizei *length,
4103 GLint64 *params)
4104{
Brandon Jonesd1049182018-03-28 10:02:20 -07004105 GLsizei numParams = 0;
4106
Geoff Langebebe1c2016-10-14 12:01:31 -04004107 if (!ValidateRobustEntryPoint(context, bufSize))
4108 {
4109 return false;
4110 }
4111
Brandon Jonesd1049182018-03-28 10:02:20 -07004112 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004113 {
4114 return false;
4115 }
4116
Brandon Jonesd1049182018-03-28 10:02:20 -07004117 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004118 {
4119 return false;
4120 }
4121
Brandon Jonesd1049182018-03-28 10:02:20 -07004122 SetRobustLengthParam(length, numParams);
4123
Geoff Langff5b2d52016-09-07 11:32:23 -04004124 return true;
4125}
4126
Jamie Madill5b772312018-03-08 20:28:32 -05004127bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004128{
4129 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004130 if (numParams)
4131 {
4132 *numParams = 1;
4133 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004134
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004135 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4136 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4137 ? GetValidProgramNoResolve(context, program)
4138 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004139 if (!programObject)
4140 {
4141 return false;
4142 }
4143
4144 switch (pname)
4145 {
4146 case GL_DELETE_STATUS:
4147 case GL_LINK_STATUS:
4148 case GL_VALIDATE_STATUS:
4149 case GL_INFO_LOG_LENGTH:
4150 case GL_ATTACHED_SHADERS:
4151 case GL_ACTIVE_ATTRIBUTES:
4152 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4153 case GL_ACTIVE_UNIFORMS:
4154 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4155 break;
4156
4157 case GL_PROGRAM_BINARY_LENGTH:
4158 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4159 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004160 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004161 return false;
4162 }
4163 break;
4164
4165 case GL_ACTIVE_UNIFORM_BLOCKS:
4166 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4167 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4168 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4169 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4170 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4171 if (context->getClientMajorVersion() < 3)
4172 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004173 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Geoff Langff5b2d52016-09-07 11:32:23 -04004174 return false;
4175 }
4176 break;
4177
Yunchao He61afff12017-03-14 15:34:03 +08004178 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004179 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004180 if (context->getClientVersion() < Version(3, 1))
4181 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004182 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao He61afff12017-03-14 15:34:03 +08004183 return false;
4184 }
4185 break;
4186
Jiawei Shao6ae51612018-02-23 14:03:25 +08004187 case GL_COMPUTE_WORK_GROUP_SIZE:
4188 if (context->getClientVersion() < Version(3, 1))
4189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004190 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004191 return false;
4192 }
4193
4194 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4195 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4196 // program which has not been linked successfully, or which does not contain objects to
4197 // form a compute shader.
4198 if (!programObject->isLinked())
4199 {
Jamie Madille0472f32018-11-27 16:32:45 -05004200 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004201 return false;
4202 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004203 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004204 {
Jamie Madille0472f32018-11-27 16:32:45 -05004205 context->validationError(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004206 return false;
4207 }
4208 break;
4209
Jiawei Shao447bfac2018-03-14 14:23:40 +08004210 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4211 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4212 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4213 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4214 if (!context->getExtensions().geometryShader)
4215 {
Jamie Madille0472f32018-11-27 16:32:45 -05004216 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004217 return false;
4218 }
4219
4220 // [EXT_geometry_shader] Chapter 7.12
4221 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4222 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4223 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4224 // successfully, or which does not contain objects to form a geometry shader.
4225 if (!programObject->isLinked())
4226 {
Jamie Madille0472f32018-11-27 16:32:45 -05004227 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004228 return false;
4229 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004230 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004231 {
Jamie Madille0472f32018-11-27 16:32:45 -05004232 context->validationError(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004233 return false;
4234 }
4235 break;
4236
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004237 case GL_COMPLETION_STATUS_KHR:
4238 if (!context->getExtensions().parallelShaderCompile)
4239 {
Jamie Madille0472f32018-11-27 16:32:45 -05004240 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004241 return false;
4242 }
4243 break;
4244
Geoff Langff5b2d52016-09-07 11:32:23 -04004245 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004246 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004247 return false;
4248 }
4249
4250 return true;
4251}
4252
4253bool ValidateGetProgramivRobustANGLE(Context *context,
4254 GLuint program,
4255 GLenum pname,
4256 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004257 GLsizei *length,
4258 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004259{
4260 if (!ValidateRobustEntryPoint(context, bufSize))
4261 {
4262 return false;
4263 }
4264
Brandon Jonesd1049182018-03-28 10:02:20 -07004265 GLsizei numParams = 0;
4266
4267 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004268 {
4269 return false;
4270 }
4271
Brandon Jonesd1049182018-03-28 10:02:20 -07004272 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004273 {
4274 return false;
4275 }
4276
Brandon Jonesd1049182018-03-28 10:02:20 -07004277 SetRobustLengthParam(length, numParams);
4278
Geoff Langff5b2d52016-09-07 11:32:23 -04004279 return true;
4280}
4281
Geoff Lang740d9022016-10-07 11:20:52 -04004282bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4283 GLenum target,
4284 GLenum pname,
4285 GLsizei bufSize,
4286 GLsizei *length,
4287 GLint *params)
4288{
4289 if (!ValidateRobustEntryPoint(context, bufSize))
4290 {
4291 return false;
4292 }
4293
Brandon Jonesd1049182018-03-28 10:02:20 -07004294 GLsizei numParams = 0;
4295
4296 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004297 {
4298 return false;
4299 }
4300
Brandon Jonesd1049182018-03-28 10:02:20 -07004301 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004302 {
4303 return false;
4304 }
4305
Brandon Jonesd1049182018-03-28 10:02:20 -07004306 SetRobustLengthParam(length, numParams);
4307
Geoff Lang740d9022016-10-07 11:20:52 -04004308 return true;
4309}
4310
Geoff Langd7d0ed32016-10-07 11:33:51 -04004311bool ValidateGetShaderivRobustANGLE(Context *context,
4312 GLuint shader,
4313 GLenum pname,
4314 GLsizei bufSize,
4315 GLsizei *length,
4316 GLint *params)
4317{
4318 if (!ValidateRobustEntryPoint(context, bufSize))
4319 {
4320 return false;
4321 }
4322
Brandon Jonesd1049182018-03-28 10:02:20 -07004323 GLsizei numParams = 0;
4324
4325 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004326 {
4327 return false;
4328 }
4329
Brandon Jonesd1049182018-03-28 10:02:20 -07004330 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004331 {
4332 return false;
4333 }
4334
Brandon Jonesd1049182018-03-28 10:02:20 -07004335 SetRobustLengthParam(length, numParams);
4336
Geoff Langd7d0ed32016-10-07 11:33:51 -04004337 return true;
4338}
4339
Geoff Langc1984ed2016-10-07 12:41:00 -04004340bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004341 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004342 GLenum pname,
4343 GLsizei bufSize,
4344 GLsizei *length,
4345 GLfloat *params)
4346{
4347 if (!ValidateRobustEntryPoint(context, bufSize))
4348 {
4349 return false;
4350 }
4351
Brandon Jonesd1049182018-03-28 10:02:20 -07004352 GLsizei numParams = 0;
4353
4354 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004355 {
4356 return false;
4357 }
4358
Brandon Jonesd1049182018-03-28 10:02:20 -07004359 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004360 {
4361 return false;
4362 }
4363
Brandon Jonesd1049182018-03-28 10:02:20 -07004364 SetRobustLengthParam(length, numParams);
4365
Geoff Langc1984ed2016-10-07 12:41:00 -04004366 return true;
4367}
4368
Geoff Langc1984ed2016-10-07 12:41:00 -04004369bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004370 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004371 GLenum pname,
4372 GLsizei bufSize,
4373 GLsizei *length,
4374 GLint *params)
4375{
Brandon Jonesd1049182018-03-28 10:02:20 -07004376
Geoff Langc1984ed2016-10-07 12:41:00 -04004377 if (!ValidateRobustEntryPoint(context, bufSize))
4378 {
4379 return false;
4380 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004381 GLsizei numParams = 0;
4382 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004383 {
4384 return false;
4385 }
4386
Brandon Jonesd1049182018-03-28 10:02:20 -07004387 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004388 {
4389 return false;
4390 }
4391
Brandon Jonesd1049182018-03-28 10:02:20 -07004392 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004393 return true;
4394}
4395
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004396bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4397 TextureType target,
4398 GLenum pname,
4399 GLsizei bufSize,
4400 GLsizei *length,
4401 GLint *params)
4402{
4403 UNIMPLEMENTED();
4404 return false;
4405}
4406
4407bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4408 TextureType target,
4409 GLenum pname,
4410 GLsizei bufSize,
4411 GLsizei *length,
4412 GLuint *params)
4413{
4414 UNIMPLEMENTED();
4415 return false;
4416}
4417
Geoff Langc1984ed2016-10-07 12:41:00 -04004418bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004419 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004420 GLenum pname,
4421 GLsizei bufSize,
4422 const GLfloat *params)
4423{
4424 if (!ValidateRobustEntryPoint(context, bufSize))
4425 {
4426 return false;
4427 }
4428
Till Rathmannb8543632018-10-02 19:46:14 +02004429 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004430}
4431
Geoff Langc1984ed2016-10-07 12:41:00 -04004432bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004433 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004434 GLenum pname,
4435 GLsizei bufSize,
4436 const GLint *params)
4437{
4438 if (!ValidateRobustEntryPoint(context, bufSize))
4439 {
4440 return false;
4441 }
4442
Till Rathmannb8543632018-10-02 19:46:14 +02004443 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004444}
4445
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004446bool ValidateTexParameterIivRobustANGLE(Context *context,
4447 TextureType target,
4448 GLenum pname,
4449 GLsizei bufSize,
4450 const GLint *params)
4451{
4452 UNIMPLEMENTED();
4453 return false;
4454}
4455
4456bool ValidateTexParameterIuivRobustANGLE(Context *context,
4457 TextureType target,
4458 GLenum pname,
4459 GLsizei bufSize,
4460 const GLuint *params)
4461{
4462 UNIMPLEMENTED();
4463 return false;
4464}
4465
Geoff Langc1984ed2016-10-07 12:41:00 -04004466bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4467 GLuint sampler,
4468 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004469 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004470 GLsizei *length,
4471 GLfloat *params)
4472{
4473 if (!ValidateRobustEntryPoint(context, bufSize))
4474 {
4475 return false;
4476 }
4477
Brandon Jonesd1049182018-03-28 10:02:20 -07004478 GLsizei numParams = 0;
4479
4480 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004481 {
4482 return false;
4483 }
4484
Brandon Jonesd1049182018-03-28 10:02:20 -07004485 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004486 {
4487 return false;
4488 }
4489
Brandon Jonesd1049182018-03-28 10:02:20 -07004490 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004491 return true;
4492}
4493
Geoff Langc1984ed2016-10-07 12:41:00 -04004494bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4495 GLuint sampler,
4496 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004497 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004498 GLsizei *length,
4499 GLint *params)
4500{
4501 if (!ValidateRobustEntryPoint(context, bufSize))
4502 {
4503 return false;
4504 }
4505
Brandon Jonesd1049182018-03-28 10:02:20 -07004506 GLsizei numParams = 0;
4507
4508 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004509 {
4510 return false;
4511 }
4512
Brandon Jonesd1049182018-03-28 10:02:20 -07004513 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004514 {
4515 return false;
4516 }
4517
Brandon Jonesd1049182018-03-28 10:02:20 -07004518 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004519 return true;
4520}
4521
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004522bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4523 GLuint sampler,
4524 GLenum pname,
4525 GLsizei bufSize,
4526 GLsizei *length,
4527 GLint *params)
4528{
4529 UNIMPLEMENTED();
4530 return false;
4531}
4532
4533bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4534 GLuint sampler,
4535 GLenum pname,
4536 GLsizei bufSize,
4537 GLsizei *length,
4538 GLuint *params)
4539{
4540 UNIMPLEMENTED();
4541 return false;
4542}
4543
Geoff Langc1984ed2016-10-07 12:41:00 -04004544bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4545 GLuint sampler,
4546 GLenum pname,
4547 GLsizei bufSize,
4548 const GLfloat *params)
4549{
4550 if (!ValidateRobustEntryPoint(context, bufSize))
4551 {
4552 return false;
4553 }
4554
Till Rathmannb8543632018-10-02 19:46:14 +02004555 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004556}
4557
Geoff Langc1984ed2016-10-07 12:41:00 -04004558bool ValidateSamplerParameterivRobustANGLE(Context *context,
4559 GLuint sampler,
4560 GLenum pname,
4561 GLsizei bufSize,
4562 const GLint *params)
4563{
4564 if (!ValidateRobustEntryPoint(context, bufSize))
4565 {
4566 return false;
4567 }
4568
Till Rathmannb8543632018-10-02 19:46:14 +02004569 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004570}
4571
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004572bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4573 GLuint sampler,
4574 GLenum pname,
4575 GLsizei bufSize,
4576 const GLint *param)
4577{
4578 UNIMPLEMENTED();
4579 return false;
4580}
4581
4582bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4583 GLuint sampler,
4584 GLenum pname,
4585 GLsizei bufSize,
4586 const GLuint *param)
4587{
4588 UNIMPLEMENTED();
4589 return false;
4590}
4591
Geoff Lang0b031062016-10-13 14:30:04 -04004592bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4593 GLuint index,
4594 GLenum pname,
4595 GLsizei bufSize,
4596 GLsizei *length,
4597 GLfloat *params)
4598{
4599 if (!ValidateRobustEntryPoint(context, bufSize))
4600 {
4601 return false;
4602 }
4603
Brandon Jonesd1049182018-03-28 10:02:20 -07004604 GLsizei writeLength = 0;
4605
4606 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004607 {
4608 return false;
4609 }
4610
Brandon Jonesd1049182018-03-28 10:02:20 -07004611 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004612 {
4613 return false;
4614 }
4615
Brandon Jonesd1049182018-03-28 10:02:20 -07004616 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004617 return true;
4618}
4619
Geoff Lang0b031062016-10-13 14:30:04 -04004620bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4621 GLuint index,
4622 GLenum pname,
4623 GLsizei bufSize,
4624 GLsizei *length,
4625 GLint *params)
4626{
4627 if (!ValidateRobustEntryPoint(context, bufSize))
4628 {
4629 return false;
4630 }
4631
Brandon Jonesd1049182018-03-28 10:02:20 -07004632 GLsizei writeLength = 0;
4633
4634 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004635 {
4636 return false;
4637 }
4638
Brandon Jonesd1049182018-03-28 10:02:20 -07004639 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004640 {
4641 return false;
4642 }
4643
Brandon Jonesd1049182018-03-28 10:02:20 -07004644 SetRobustLengthParam(length, writeLength);
4645
Geoff Lang0b031062016-10-13 14:30:04 -04004646 return true;
4647}
4648
Geoff Lang0b031062016-10-13 14:30:04 -04004649bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4650 GLuint index,
4651 GLenum pname,
4652 GLsizei bufSize,
4653 GLsizei *length,
4654 void **pointer)
4655{
4656 if (!ValidateRobustEntryPoint(context, bufSize))
4657 {
4658 return false;
4659 }
4660
Brandon Jonesd1049182018-03-28 10:02:20 -07004661 GLsizei writeLength = 0;
4662
4663 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004664 {
4665 return false;
4666 }
4667
Brandon Jonesd1049182018-03-28 10:02:20 -07004668 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004669 {
4670 return false;
4671 }
4672
Brandon Jonesd1049182018-03-28 10:02:20 -07004673 SetRobustLengthParam(length, writeLength);
4674
Geoff Lang0b031062016-10-13 14:30:04 -04004675 return true;
4676}
4677
Geoff Lang0b031062016-10-13 14:30:04 -04004678bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4679 GLuint index,
4680 GLenum pname,
4681 GLsizei bufSize,
4682 GLsizei *length,
4683 GLint *params)
4684{
4685 if (!ValidateRobustEntryPoint(context, bufSize))
4686 {
4687 return false;
4688 }
4689
Brandon Jonesd1049182018-03-28 10:02:20 -07004690 GLsizei writeLength = 0;
4691
4692 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004693 {
4694 return false;
4695 }
4696
Brandon Jonesd1049182018-03-28 10:02:20 -07004697 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004698 {
4699 return false;
4700 }
4701
Brandon Jonesd1049182018-03-28 10:02:20 -07004702 SetRobustLengthParam(length, writeLength);
4703
Geoff Lang0b031062016-10-13 14:30:04 -04004704 return true;
4705}
4706
Geoff Lang0b031062016-10-13 14:30:04 -04004707bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
4708 GLuint index,
4709 GLenum pname,
4710 GLsizei bufSize,
4711 GLsizei *length,
4712 GLuint *params)
4713{
4714 if (!ValidateRobustEntryPoint(context, bufSize))
4715 {
4716 return false;
4717 }
4718
Brandon Jonesd1049182018-03-28 10:02:20 -07004719 GLsizei writeLength = 0;
4720
4721 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004722 {
4723 return false;
4724 }
4725
Brandon Jonesd1049182018-03-28 10:02:20 -07004726 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004727 {
4728 return false;
4729 }
4730
Brandon Jonesd1049182018-03-28 10:02:20 -07004731 SetRobustLengthParam(length, writeLength);
4732
Geoff Lang0b031062016-10-13 14:30:04 -04004733 return true;
4734}
4735
Geoff Lang6899b872016-10-14 11:30:13 -04004736bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
4737 GLuint program,
4738 GLuint uniformBlockIndex,
4739 GLenum pname,
4740 GLsizei bufSize,
4741 GLsizei *length,
4742 GLint *params)
4743{
4744 if (!ValidateRobustEntryPoint(context, bufSize))
4745 {
4746 return false;
4747 }
4748
Brandon Jonesd1049182018-03-28 10:02:20 -07004749 GLsizei writeLength = 0;
4750
4751 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
4752 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04004753 {
4754 return false;
4755 }
4756
Brandon Jonesd1049182018-03-28 10:02:20 -07004757 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04004758 {
4759 return false;
4760 }
4761
Brandon Jonesd1049182018-03-28 10:02:20 -07004762 SetRobustLengthParam(length, writeLength);
4763
Geoff Lang6899b872016-10-14 11:30:13 -04004764 return true;
4765}
4766
Brandon Jones416aaf92018-04-10 08:10:16 -07004767bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07004768 GLenum target,
4769 GLenum internalformat,
4770 GLenum pname,
4771 GLsizei bufSize,
4772 GLsizei *length,
4773 GLint *params)
4774{
4775 if (!ValidateRobustEntryPoint(context, bufSize))
4776 {
4777 return false;
4778 }
4779
Brandon Jonesd1049182018-03-28 10:02:20 -07004780 GLsizei numParams = 0;
4781
4782 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4783 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07004784 {
4785 return false;
4786 }
4787
Brandon Jonesd1049182018-03-28 10:02:20 -07004788 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07004789 {
4790 return false;
4791 }
4792
Brandon Jonesd1049182018-03-28 10:02:20 -07004793 SetRobustLengthParam(length, numParams);
4794
Geoff Lang0a9661f2016-10-20 10:59:20 -07004795 return true;
4796}
4797
Jamie Madill5b772312018-03-08 20:28:32 -05004798bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08004799 GLuint attribIndex,
4800 GLint size,
4801 GLenum type,
4802 GLboolean pureInteger)
4803{
4804 const Caps &caps = context->getCaps();
4805 if (attribIndex >= caps.maxVertexAttributes)
4806 {
Jamie Madille0472f32018-11-27 16:32:45 -05004807 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08004808 return false;
4809 }
4810
4811 if (size < 1 || size > 4)
4812 {
Jamie Madille0472f32018-11-27 16:32:45 -05004813 context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04004814 return false;
Shao80957d92017-02-20 21:25:59 +08004815 }
4816
4817 switch (type)
4818 {
4819 case GL_BYTE:
4820 case GL_UNSIGNED_BYTE:
4821 case GL_SHORT:
4822 case GL_UNSIGNED_SHORT:
4823 break;
4824
4825 case GL_INT:
4826 case GL_UNSIGNED_INT:
4827 if (context->getClientMajorVersion() < 3)
4828 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004829 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004830 return false;
4831 }
4832 break;
4833
4834 case GL_FIXED:
4835 case GL_FLOAT:
4836 if (pureInteger)
4837 {
Jamie Madille0472f32018-11-27 16:32:45 -05004838 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004839 return false;
4840 }
4841 break;
4842
4843 case GL_HALF_FLOAT:
4844 if (context->getClientMajorVersion() < 3)
4845 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004846 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004847 return false;
4848 }
4849 if (pureInteger)
4850 {
Jamie Madille0472f32018-11-27 16:32:45 -05004851 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004852 return false;
4853 }
4854 break;
4855
4856 case GL_INT_2_10_10_10_REV:
4857 case GL_UNSIGNED_INT_2_10_10_10_REV:
4858 if (context->getClientMajorVersion() < 3)
4859 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004860 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004861 return false;
4862 }
4863 if (pureInteger)
4864 {
Jamie Madille0472f32018-11-27 16:32:45 -05004865 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004866 return false;
4867 }
4868 if (size != 4)
4869 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004870 context->validationError(GL_INVALID_OPERATION, kInvalidVertexAttribSize2101010);
Shao80957d92017-02-20 21:25:59 +08004871 return false;
4872 }
4873 break;
4874
4875 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004876 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08004877 return false;
4878 }
4879
4880 return true;
4881}
4882
Geoff Lang76e65652017-03-27 14:58:02 -04004883// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
4884// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
4885// specified clear value and the type of a buffer that is being cleared generates an
4886// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05004887bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04004888 GLint drawbuffer,
4889 const GLenum *validComponentTypes,
4890 size_t validComponentTypeCount)
4891{
4892 const FramebufferAttachment *attachment =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004893 context->getState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
Geoff Lang76e65652017-03-27 14:58:02 -04004894 if (attachment)
4895 {
4896 GLenum componentType = attachment->getFormat().info->componentType;
4897 const GLenum *end = validComponentTypes + validComponentTypeCount;
4898 if (std::find(validComponentTypes, end, componentType) == end)
4899 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004900 context->validationError(GL_INVALID_OPERATION, kNoDefinedClearConversion);
Geoff Lang76e65652017-03-27 14:58:02 -04004901 return false;
4902 }
4903 }
4904
4905 return true;
4906}
4907
Jamie Madill5b772312018-03-08 20:28:32 -05004908bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04004909{
4910 if (!ValidateRobustEntryPoint(context, dataSize))
4911 {
4912 return false;
4913 }
4914
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004915 Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04004916 if (pixelUnpackBuffer == nullptr)
4917 {
4918 if (dataSize < imageSize)
4919 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004920 context->validationError(GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
Corentin Wallezb2931602017-04-11 15:58:57 -04004921 }
4922 }
4923 return true;
4924}
4925
Jamie Madill5b772312018-03-08 20:28:32 -05004926bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004927 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04004928 GLenum pname,
4929 bool pointerVersion,
4930 GLsizei *numParams)
4931{
4932 if (numParams)
4933 {
4934 *numParams = 0;
4935 }
4936
Corentin Walleze4477002017-12-01 14:39:58 -05004937 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04004938 {
Jamie Madille0472f32018-11-27 16:32:45 -05004939 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04004940 return false;
4941 }
4942
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004943 const Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04004944 if (!buffer)
4945 {
4946 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05004947 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04004948 return false;
4949 }
4950
4951 const Extensions &extensions = context->getExtensions();
4952
4953 switch (pname)
4954 {
4955 case GL_BUFFER_USAGE:
4956 case GL_BUFFER_SIZE:
4957 break;
4958
4959 case GL_BUFFER_ACCESS_OES:
4960 if (!extensions.mapBuffer)
4961 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004962 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004963 return false;
4964 }
4965 break;
4966
4967 case GL_BUFFER_MAPPED:
4968 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
4969 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
4970 !extensions.mapBufferRange)
4971 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004972 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004973 return false;
4974 }
4975 break;
4976
4977 case GL_BUFFER_MAP_POINTER:
4978 if (!pointerVersion)
4979 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004980 context->validationError(GL_INVALID_ENUM, kInvalidMapPointerQuery);
Jamie Madillbe849e42017-05-02 15:49:00 -04004981 return false;
4982 }
4983 break;
4984
4985 case GL_BUFFER_ACCESS_FLAGS:
4986 case GL_BUFFER_MAP_OFFSET:
4987 case GL_BUFFER_MAP_LENGTH:
4988 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
4989 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004990 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004991 return false;
4992 }
4993 break;
4994
Geoff Lang79b91402018-10-04 15:11:30 -04004995 case GL_MEMORY_SIZE_ANGLE:
4996 if (!context->getExtensions().memorySize)
4997 {
Jamie Madille0472f32018-11-27 16:32:45 -05004998 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04004999 return false;
5000 }
5001 break;
5002
Jamie Madillbe849e42017-05-02 15:49:00 -04005003 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005004 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005005 return false;
5006 }
5007
5008 // All buffer parameter queries return one value.
5009 if (numParams)
5010 {
5011 *numParams = 1;
5012 }
5013
5014 return true;
5015}
5016
5017bool ValidateGetRenderbufferParameterivBase(Context *context,
5018 GLenum target,
5019 GLenum pname,
5020 GLsizei *length)
5021{
5022 if (length)
5023 {
5024 *length = 0;
5025 }
5026
5027 if (target != GL_RENDERBUFFER)
5028 {
Jamie Madille0472f32018-11-27 16:32:45 -05005029 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005030 return false;
5031 }
5032
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005033 Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005034 if (renderbuffer == nullptr)
5035 {
Jamie Madille0472f32018-11-27 16:32:45 -05005036 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005037 return false;
5038 }
5039
5040 switch (pname)
5041 {
5042 case GL_RENDERBUFFER_WIDTH:
5043 case GL_RENDERBUFFER_HEIGHT:
5044 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5045 case GL_RENDERBUFFER_RED_SIZE:
5046 case GL_RENDERBUFFER_GREEN_SIZE:
5047 case GL_RENDERBUFFER_BLUE_SIZE:
5048 case GL_RENDERBUFFER_ALPHA_SIZE:
5049 case GL_RENDERBUFFER_DEPTH_SIZE:
5050 case GL_RENDERBUFFER_STENCIL_SIZE:
5051 break;
5052
5053 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5054 if (!context->getExtensions().framebufferMultisample)
5055 {
Jamie Madille0472f32018-11-27 16:32:45 -05005056 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005057 return false;
5058 }
5059 break;
5060
Geoff Lang79b91402018-10-04 15:11:30 -04005061 case GL_MEMORY_SIZE_ANGLE:
5062 if (!context->getExtensions().memorySize)
5063 {
Jamie Madille0472f32018-11-27 16:32:45 -05005064 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005065 return false;
5066 }
5067 break;
5068
Jamie Madillbe849e42017-05-02 15:49:00 -04005069 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005070 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005071 return false;
5072 }
5073
5074 if (length)
5075 {
5076 *length = 1;
5077 }
5078 return true;
5079}
5080
5081bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5082{
5083 if (length)
5084 {
5085 *length = 0;
5086 }
5087
5088 if (GetValidShader(context, shader) == nullptr)
5089 {
5090 return false;
5091 }
5092
5093 switch (pname)
5094 {
5095 case GL_SHADER_TYPE:
5096 case GL_DELETE_STATUS:
5097 case GL_COMPILE_STATUS:
5098 case GL_INFO_LOG_LENGTH:
5099 case GL_SHADER_SOURCE_LENGTH:
5100 break;
5101
5102 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5103 if (!context->getExtensions().translatedShaderSource)
5104 {
Jamie Madille0472f32018-11-27 16:32:45 -05005105 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005106 return false;
5107 }
5108 break;
5109
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005110 case GL_COMPLETION_STATUS_KHR:
5111 if (!context->getExtensions().parallelShaderCompile)
5112 {
Jamie Madille0472f32018-11-27 16:32:45 -05005113 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005114 return false;
5115 }
5116 break;
5117
Jamie Madillbe849e42017-05-02 15:49:00 -04005118 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005119 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005120 return false;
5121 }
5122
5123 if (length)
5124 {
5125 *length = 1;
5126 }
5127 return true;
5128}
5129
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005130bool ValidateGetTexParameterBase(Context *context,
5131 TextureType target,
5132 GLenum pname,
5133 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005134{
5135 if (length)
5136 {
5137 *length = 0;
5138 }
5139
5140 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5141 {
Jamie Madille0472f32018-11-27 16:32:45 -05005142 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005143 return false;
5144 }
5145
5146 if (context->getTargetTexture(target) == nullptr)
5147 {
5148 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005149 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005150 return false;
5151 }
5152
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005153 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5154 {
Jamie Madille0472f32018-11-27 16:32:45 -05005155 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005156 return false;
5157 }
5158
Jamie Madillbe849e42017-05-02 15:49:00 -04005159 switch (pname)
5160 {
5161 case GL_TEXTURE_MAG_FILTER:
5162 case GL_TEXTURE_MIN_FILTER:
5163 case GL_TEXTURE_WRAP_S:
5164 case GL_TEXTURE_WRAP_T:
5165 break;
5166
5167 case GL_TEXTURE_USAGE_ANGLE:
5168 if (!context->getExtensions().textureUsage)
5169 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005170 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005171 return false;
5172 }
5173 break;
5174
5175 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005176 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005177 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005178 return false;
5179 }
5180 break;
5181
5182 case GL_TEXTURE_IMMUTABLE_FORMAT:
5183 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5184 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005185 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005186 return false;
5187 }
5188 break;
5189
5190 case GL_TEXTURE_WRAP_R:
5191 case GL_TEXTURE_IMMUTABLE_LEVELS:
5192 case GL_TEXTURE_SWIZZLE_R:
5193 case GL_TEXTURE_SWIZZLE_G:
5194 case GL_TEXTURE_SWIZZLE_B:
5195 case GL_TEXTURE_SWIZZLE_A:
5196 case GL_TEXTURE_BASE_LEVEL:
5197 case GL_TEXTURE_MAX_LEVEL:
5198 case GL_TEXTURE_MIN_LOD:
5199 case GL_TEXTURE_MAX_LOD:
5200 case GL_TEXTURE_COMPARE_MODE:
5201 case GL_TEXTURE_COMPARE_FUNC:
5202 if (context->getClientMajorVersion() < 3)
5203 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005204 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Jamie Madillbe849e42017-05-02 15:49:00 -04005205 return false;
5206 }
5207 break;
5208
5209 case GL_TEXTURE_SRGB_DECODE_EXT:
5210 if (!context->getExtensions().textureSRGBDecode)
5211 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005212 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005213 return false;
5214 }
5215 break;
5216
Yunchao Hebacaa712018-01-30 14:01:39 +08005217 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5218 if (context->getClientVersion() < Version(3, 1))
5219 {
Jamie Madille0472f32018-11-27 16:32:45 -05005220 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005221 return false;
5222 }
5223 break;
5224
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005225 case GL_GENERATE_MIPMAP:
5226 case GL_TEXTURE_CROP_RECT_OES:
5227 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5228 // after GL_OES_draw_texture functionality implemented
5229 if (context->getClientMajorVersion() > 1)
5230 {
Jamie Madille0472f32018-11-27 16:32:45 -05005231 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005232 return false;
5233 }
5234 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005235
5236 case GL_MEMORY_SIZE_ANGLE:
5237 if (!context->getExtensions().memorySize)
5238 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005239 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang79b91402018-10-04 15:11:30 -04005240 return false;
5241 }
5242 break;
5243
Till Rathmannb8543632018-10-02 19:46:14 +02005244 case GL_TEXTURE_BORDER_COLOR:
5245 if (!context->getExtensions().textureBorderClamp)
5246 {
Jamie Madille0472f32018-11-27 16:32:45 -05005247 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005248 return false;
5249 }
5250 break;
5251
Jamie Madillbe849e42017-05-02 15:49:00 -04005252 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005253 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005254 return false;
5255 }
5256
5257 if (length)
5258 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005259 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005260 }
5261 return true;
5262}
5263
5264bool ValidateGetVertexAttribBase(Context *context,
5265 GLuint index,
5266 GLenum pname,
5267 GLsizei *length,
5268 bool pointer,
5269 bool pureIntegerEntryPoint)
5270{
5271 if (length)
5272 {
5273 *length = 0;
5274 }
5275
5276 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5277 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005278 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005279 return false;
5280 }
5281
5282 if (index >= context->getCaps().maxVertexAttributes)
5283 {
Jamie Madille0472f32018-11-27 16:32:45 -05005284 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005285 return false;
5286 }
5287
5288 if (pointer)
5289 {
5290 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5291 {
Jamie Madille0472f32018-11-27 16:32:45 -05005292 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005293 return false;
5294 }
5295 }
5296 else
5297 {
5298 switch (pname)
5299 {
5300 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5301 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5302 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5303 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5304 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5305 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5306 case GL_CURRENT_VERTEX_ATTRIB:
5307 break;
5308
5309 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5310 static_assert(
5311 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5312 "ANGLE extension enums not equal to GL enums.");
5313 if (context->getClientMajorVersion() < 3 &&
5314 !context->getExtensions().instancedArrays)
5315 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005316 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005317 return false;
5318 }
5319 break;
5320
5321 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5322 if (context->getClientMajorVersion() < 3)
5323 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005324 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005325 return false;
5326 }
5327 break;
5328
5329 case GL_VERTEX_ATTRIB_BINDING:
5330 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5331 if (context->getClientVersion() < ES_3_1)
5332 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005333 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005334 return false;
5335 }
5336 break;
5337
5338 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005339 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005340 return false;
5341 }
5342 }
5343
5344 if (length)
5345 {
5346 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5347 {
5348 *length = 4;
5349 }
5350 else
5351 {
5352 *length = 1;
5353 }
5354 }
5355
5356 return true;
5357}
5358
Jamie Madill4928b7c2017-06-20 12:57:39 -04005359bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005360 GLint x,
5361 GLint y,
5362 GLsizei width,
5363 GLsizei height,
5364 GLenum format,
5365 GLenum type,
5366 GLsizei bufSize,
5367 GLsizei *length,
5368 GLsizei *columns,
5369 GLsizei *rows,
5370 void *pixels)
5371{
5372 if (length != nullptr)
5373 {
5374 *length = 0;
5375 }
5376 if (rows != nullptr)
5377 {
5378 *rows = 0;
5379 }
5380 if (columns != nullptr)
5381 {
5382 *columns = 0;
5383 }
5384
5385 if (width < 0 || height < 0)
5386 {
Jamie Madille0472f32018-11-27 16:32:45 -05005387 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005388 return false;
5389 }
5390
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005391 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005392
Jamie Madill427064d2018-04-13 16:20:34 -04005393 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005394 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005395 return false;
5396 }
5397
Jamie Madille98b1b52018-03-08 09:47:23 -05005398 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005399 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005400 return false;
5401 }
5402
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005403 Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005404 ASSERT(framebuffer);
5405
5406 if (framebuffer->getReadBufferState() == GL_NONE)
5407 {
Jamie Madille0472f32018-11-27 16:32:45 -05005408 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005409 return false;
5410 }
5411
5412 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5413 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5414 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5415 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5416 // situation is an application error that would lead to a crash in ANGLE.
5417 if (readBuffer == nullptr)
5418 {
Jamie Madille0472f32018-11-27 16:32:45 -05005419 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005420 return false;
5421 }
5422
Martin Radev28031682017-07-28 14:47:56 +03005423 // ANGLE_multiview, Revision 1:
5424 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005425 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5426 // in the current read framebuffer is more than one.
5427 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005428 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005429 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
Martin Radev28031682017-07-28 14:47:56 +03005430 return false;
5431 }
5432
Geoff Lang280ba992017-04-18 16:30:58 -04005433 if (context->getExtensions().webglCompatibility)
5434 {
5435 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5436 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5437 // and type before validating the combination of format and type. However, the
5438 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5439 // verifies that GL_INVALID_OPERATION is generated.
5440 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5441 // dEQP/WebGL.
5442 if (!ValidReadPixelsFormatEnum(context, format))
5443 {
Jamie Madille0472f32018-11-27 16:32:45 -05005444 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005445 return false;
5446 }
5447
5448 if (!ValidReadPixelsTypeEnum(context, type))
5449 {
Jamie Madille0472f32018-11-27 16:32:45 -05005450 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005451 return false;
5452 }
5453 }
5454
Jamie Madill690c8eb2018-03-12 15:20:03 -04005455 GLenum currentFormat = GL_NONE;
5456 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5457
5458 GLenum currentType = GL_NONE;
5459 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5460
Jamie Madillbe849e42017-05-02 15:49:00 -04005461 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5462
5463 bool validFormatTypeCombination =
5464 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5465
5466 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5467 {
Jamie Madille0472f32018-11-27 16:32:45 -05005468 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005469 return false;
5470 }
5471
5472 // Check for pixel pack buffer related API errors
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005473 Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005474 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5475 {
5476 // ...the buffer object's data store is currently mapped.
Jamie Madillc3e37312018-11-30 15:25:39 -05005477 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madillbe849e42017-05-02 15:49:00 -04005478 return false;
5479 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005480 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5481 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5482 {
Jamie Madille0472f32018-11-27 16:32:45 -05005483 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005484 return false;
5485 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005486
5487 // .. the data would be packed to the buffer object such that the memory writes required
5488 // would exceed the data store size.
5489 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005490 const Extents size(width, height, 1);
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005491 const auto &pack = context->getState().getPackState();
Jamie Madillbe849e42017-05-02 15:49:00 -04005492
Jamie Madillca2ff382018-07-11 09:01:17 -04005493 GLuint endByte = 0;
5494 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005495 {
Jamie Madille0472f32018-11-27 16:32:45 -05005496 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005497 return false;
5498 }
5499
Jamie Madillbe849e42017-05-02 15:49:00 -04005500 if (bufSize >= 0)
5501 {
5502 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5503 {
Jamie Madille0472f32018-11-27 16:32:45 -05005504 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005505 return false;
5506 }
5507 }
5508
5509 if (pixelPackBuffer != nullptr)
5510 {
5511 CheckedNumeric<size_t> checkedEndByte(endByte);
5512 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5513 checkedEndByte += checkedOffset;
5514
5515 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5516 {
5517 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005518 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005519 return false;
5520 }
5521 }
5522
5523 if (pixelPackBuffer == nullptr && length != nullptr)
5524 {
5525 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5526 {
Jamie Madille0472f32018-11-27 16:32:45 -05005527 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005528 return false;
5529 }
5530
5531 *length = static_cast<GLsizei>(endByte);
5532 }
5533
Geoff Langa953b522018-02-21 16:56:23 -05005534 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005535 angle::CheckedNumeric<int> clippedExtent(length);
5536 if (start < 0)
5537 {
5538 // "subtract" the area that is less than 0
5539 clippedExtent += start;
5540 }
5541
Geoff Langa953b522018-02-21 16:56:23 -05005542 angle::CheckedNumeric<int> readExtent = start;
5543 readExtent += length;
5544 if (!readExtent.IsValid())
5545 {
5546 return false;
5547 }
5548
5549 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005550 {
5551 // Subtract the region to the right of the read buffer
5552 clippedExtent -= (readExtent - bufferSize);
5553 }
5554
5555 if (!clippedExtent.IsValid())
5556 {
Geoff Langa953b522018-02-21 16:56:23 -05005557 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005558 }
5559
Geoff Langa953b522018-02-21 16:56:23 -05005560 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5561 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005562 };
5563
Geoff Langa953b522018-02-21 16:56:23 -05005564 GLsizei writtenColumns = 0;
5565 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5566 {
Jamie Madille0472f32018-11-27 16:32:45 -05005567 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005568 return false;
5569 }
5570
5571 GLsizei writtenRows = 0;
5572 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5573 {
Jamie Madille0472f32018-11-27 16:32:45 -05005574 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005575 return false;
5576 }
5577
Jamie Madillbe849e42017-05-02 15:49:00 -04005578 if (columns != nullptr)
5579 {
Geoff Langa953b522018-02-21 16:56:23 -05005580 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005581 }
5582
5583 if (rows != nullptr)
5584 {
Geoff Langa953b522018-02-21 16:56:23 -05005585 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005586 }
5587
5588 return true;
5589}
5590
5591template <typename ParamType>
5592bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005593 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005594 GLenum pname,
5595 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005596 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005597 const ParamType *params)
5598{
5599 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5600 {
Jamie Madille0472f32018-11-27 16:32:45 -05005601 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005602 return false;
5603 }
5604
5605 if (context->getTargetTexture(target) == nullptr)
5606 {
5607 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005608 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005609 return false;
5610 }
5611
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005612 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005613 if (bufSize >= 0 && bufSize < minBufSize)
5614 {
Jamie Madille0472f32018-11-27 16:32:45 -05005615 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005616 return false;
5617 }
5618
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005619 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5620 {
Jamie Madille0472f32018-11-27 16:32:45 -05005621 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005622 return false;
5623 }
5624
Jamie Madillbe849e42017-05-02 15:49:00 -04005625 switch (pname)
5626 {
5627 case GL_TEXTURE_WRAP_R:
5628 case GL_TEXTURE_SWIZZLE_R:
5629 case GL_TEXTURE_SWIZZLE_G:
5630 case GL_TEXTURE_SWIZZLE_B:
5631 case GL_TEXTURE_SWIZZLE_A:
5632 case GL_TEXTURE_BASE_LEVEL:
5633 case GL_TEXTURE_MAX_LEVEL:
5634 case GL_TEXTURE_COMPARE_MODE:
5635 case GL_TEXTURE_COMPARE_FUNC:
5636 case GL_TEXTURE_MIN_LOD:
5637 case GL_TEXTURE_MAX_LOD:
5638 if (context->getClientMajorVersion() < 3)
5639 {
Jamie Madille0472f32018-11-27 16:32:45 -05005640 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005641 return false;
5642 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005643 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005644 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005645 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005646 return false;
5647 }
5648 break;
5649
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005650 case GL_GENERATE_MIPMAP:
5651 case GL_TEXTURE_CROP_RECT_OES:
5652 if (context->getClientMajorVersion() > 1)
5653 {
Jamie Madille0472f32018-11-27 16:32:45 -05005654 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005655 return false;
5656 }
5657 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005658 default:
5659 break;
5660 }
5661
Olli Etuahod310a432018-08-24 15:40:23 +03005662 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005663 {
5664 switch (pname)
5665 {
5666 case GL_TEXTURE_MIN_FILTER:
5667 case GL_TEXTURE_MAG_FILTER:
5668 case GL_TEXTURE_WRAP_S:
5669 case GL_TEXTURE_WRAP_T:
5670 case GL_TEXTURE_WRAP_R:
5671 case GL_TEXTURE_MIN_LOD:
5672 case GL_TEXTURE_MAX_LOD:
5673 case GL_TEXTURE_COMPARE_MODE:
5674 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005675 case GL_TEXTURE_BORDER_COLOR:
Jamie Madillc3e37312018-11-30 15:25:39 -05005676 context->validationError(GL_INVALID_ENUM, kInvalidPname);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005677 return false;
5678 }
5679 }
5680
Jamie Madillbe849e42017-05-02 15:49:00 -04005681 switch (pname)
5682 {
5683 case GL_TEXTURE_WRAP_S:
5684 case GL_TEXTURE_WRAP_T:
5685 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005686 {
5687 bool restrictedWrapModes =
5688 target == TextureType::External || target == TextureType::Rectangle;
5689 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04005690 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005691 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005692 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005693 }
5694 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005695
5696 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005697 {
5698 bool restrictedMinFilter =
5699 target == TextureType::External || target == TextureType::Rectangle;
5700 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04005701 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005702 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005703 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005704 }
5705 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005706
5707 case GL_TEXTURE_MAG_FILTER:
5708 if (!ValidateTextureMagFilterValue(context, params))
5709 {
5710 return false;
5711 }
5712 break;
5713
5714 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04005715 if (!context->getExtensions().textureUsage)
5716 {
Jamie Madille0472f32018-11-27 16:32:45 -05005717 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04005718 return false;
5719 }
5720
Jamie Madillbe849e42017-05-02 15:49:00 -04005721 switch (ConvertToGLenum(params[0]))
5722 {
5723 case GL_NONE:
5724 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
5725 break;
5726
5727 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005728 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005729 return false;
5730 }
5731 break;
5732
5733 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005734 {
5735 GLfloat paramValue = static_cast<GLfloat>(params[0]);
5736 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04005737 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005738 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005739 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005740 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
5741 }
5742 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005743
5744 case GL_TEXTURE_MIN_LOD:
5745 case GL_TEXTURE_MAX_LOD:
5746 // any value is permissible
5747 break;
5748
5749 case GL_TEXTURE_COMPARE_MODE:
5750 if (!ValidateTextureCompareModeValue(context, params))
5751 {
5752 return false;
5753 }
5754 break;
5755
5756 case GL_TEXTURE_COMPARE_FUNC:
5757 if (!ValidateTextureCompareFuncValue(context, params))
5758 {
5759 return false;
5760 }
5761 break;
5762
5763 case GL_TEXTURE_SWIZZLE_R:
5764 case GL_TEXTURE_SWIZZLE_G:
5765 case GL_TEXTURE_SWIZZLE_B:
5766 case GL_TEXTURE_SWIZZLE_A:
5767 switch (ConvertToGLenum(params[0]))
5768 {
5769 case GL_RED:
5770 case GL_GREEN:
5771 case GL_BLUE:
5772 case GL_ALPHA:
5773 case GL_ZERO:
5774 case GL_ONE:
5775 break;
5776
5777 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005778 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005779 return false;
5780 }
5781 break;
5782
5783 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005784 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005785 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005786 context->validationError(GL_INVALID_VALUE, kBaseLevelNegative);
Jamie Madillbe849e42017-05-02 15:49:00 -04005787 return false;
5788 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005789 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005790 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005791 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005792 return false;
5793 }
Olli Etuahod310a432018-08-24 15:40:23 +03005794 if ((target == TextureType::_2DMultisample ||
5795 target == TextureType::_2DMultisampleArray) &&
5796 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005797 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005798 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005799 return false;
5800 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005801 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005802 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005803 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005804 return false;
5805 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005806 break;
5807
5808 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005809 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005810 {
Jamie Madille0472f32018-11-27 16:32:45 -05005811 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005812 return false;
5813 }
5814 break;
5815
5816 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5817 if (context->getClientVersion() < Version(3, 1))
5818 {
Jamie Madille0472f32018-11-27 16:32:45 -05005819 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005820 return false;
5821 }
5822 switch (ConvertToGLenum(params[0]))
5823 {
5824 case GL_DEPTH_COMPONENT:
5825 case GL_STENCIL_INDEX:
5826 break;
5827
5828 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005829 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005830 return false;
5831 }
5832 break;
5833
5834 case GL_TEXTURE_SRGB_DECODE_EXT:
5835 if (!ValidateTextureSRGBDecodeValue(context, params))
5836 {
5837 return false;
5838 }
5839 break;
5840
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005841 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005842 if (context->getClientMajorVersion() > 1)
5843 {
Jamie Madille0472f32018-11-27 16:32:45 -05005844 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005845 return false;
5846 }
5847 break;
Till Rathmannb8543632018-10-02 19:46:14 +02005848
5849 case GL_TEXTURE_CROP_RECT_OES:
5850 if (context->getClientMajorVersion() > 1)
5851 {
Jamie Madille0472f32018-11-27 16:32:45 -05005852 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02005853 return false;
5854 }
5855 if (!vectorParams)
5856 {
Jamie Madille0472f32018-11-27 16:32:45 -05005857 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02005858 return false;
5859 }
5860 break;
5861
5862 case GL_TEXTURE_BORDER_COLOR:
5863 if (!context->getExtensions().textureBorderClamp)
5864 {
Jamie Madille0472f32018-11-27 16:32:45 -05005865 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005866 return false;
5867 }
5868 if (!vectorParams)
5869 {
Jamie Madille0472f32018-11-27 16:32:45 -05005870 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02005871 return false;
5872 }
5873 break;
5874
Jamie Madillbe849e42017-05-02 15:49:00 -04005875 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005876 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005877 return false;
5878 }
5879
5880 return true;
5881}
5882
Till Rathmannb8543632018-10-02 19:46:14 +02005883template bool ValidateTexParameterBase(Context *,
5884 TextureType,
5885 GLenum,
5886 GLsizei,
5887 bool,
5888 const GLfloat *);
5889template bool ValidateTexParameterBase(Context *,
5890 TextureType,
5891 GLenum,
5892 GLsizei,
5893 bool,
5894 const GLint *);
5895template bool ValidateTexParameterBase(Context *,
5896 TextureType,
5897 GLenum,
5898 GLsizei,
5899 bool,
5900 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04005901
Jamie Madill5b772312018-03-08 20:28:32 -05005902bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04005903{
5904 if (index >= MAX_VERTEX_ATTRIBS)
5905 {
Jamie Madille0472f32018-11-27 16:32:45 -05005906 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04005907 return false;
5908 }
5909
5910 return true;
5911}
5912
5913bool ValidateGetActiveUniformBlockivBase(Context *context,
5914 GLuint program,
5915 GLuint uniformBlockIndex,
5916 GLenum pname,
5917 GLsizei *length)
5918{
5919 if (length)
5920 {
5921 *length = 0;
5922 }
5923
5924 if (context->getClientMajorVersion() < 3)
5925 {
Jamie Madille0472f32018-11-27 16:32:45 -05005926 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04005927 return false;
5928 }
5929
5930 Program *programObject = GetValidProgram(context, program);
5931 if (!programObject)
5932 {
5933 return false;
5934 }
5935
5936 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
5937 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005938 context->validationError(GL_INVALID_VALUE, kIndexExceedsActiveUniformBlockCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04005939 return false;
5940 }
5941
5942 switch (pname)
5943 {
5944 case GL_UNIFORM_BLOCK_BINDING:
5945 case GL_UNIFORM_BLOCK_DATA_SIZE:
5946 case GL_UNIFORM_BLOCK_NAME_LENGTH:
5947 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
5948 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
5949 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
5950 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
5951 break;
5952
5953 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005954 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04005955 return false;
5956 }
5957
5958 if (length)
5959 {
5960 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
5961 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08005962 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04005963 programObject->getUniformBlockByIndex(uniformBlockIndex);
5964 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
5965 }
5966 else
5967 {
5968 *length = 1;
5969 }
5970 }
5971
5972 return true;
5973}
5974
Jamie Madill9696d072017-08-26 23:19:57 -04005975template <typename ParamType>
5976bool ValidateSamplerParameterBase(Context *context,
5977 GLuint sampler,
5978 GLenum pname,
5979 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005980 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04005981 ParamType *params)
5982{
5983 if (context->getClientMajorVersion() < 3)
5984 {
Jamie Madille0472f32018-11-27 16:32:45 -05005985 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04005986 return false;
5987 }
5988
5989 if (!context->isSampler(sampler))
5990 {
Jamie Madille0472f32018-11-27 16:32:45 -05005991 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04005992 return false;
5993 }
5994
Till Rathmannb8543632018-10-02 19:46:14 +02005995 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04005996 if (bufSize >= 0 && bufSize < minBufSize)
5997 {
Jamie Madille0472f32018-11-27 16:32:45 -05005998 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04005999 return false;
6000 }
6001
6002 switch (pname)
6003 {
6004 case GL_TEXTURE_WRAP_S:
6005 case GL_TEXTURE_WRAP_T:
6006 case GL_TEXTURE_WRAP_R:
6007 if (!ValidateTextureWrapModeValue(context, params, false))
6008 {
6009 return false;
6010 }
6011 break;
6012
6013 case GL_TEXTURE_MIN_FILTER:
6014 if (!ValidateTextureMinFilterValue(context, params, false))
6015 {
6016 return false;
6017 }
6018 break;
6019
6020 case GL_TEXTURE_MAG_FILTER:
6021 if (!ValidateTextureMagFilterValue(context, params))
6022 {
6023 return false;
6024 }
6025 break;
6026
6027 case GL_TEXTURE_MIN_LOD:
6028 case GL_TEXTURE_MAX_LOD:
6029 // any value is permissible
6030 break;
6031
6032 case GL_TEXTURE_COMPARE_MODE:
6033 if (!ValidateTextureCompareModeValue(context, params))
6034 {
6035 return false;
6036 }
6037 break;
6038
6039 case GL_TEXTURE_COMPARE_FUNC:
6040 if (!ValidateTextureCompareFuncValue(context, params))
6041 {
6042 return false;
6043 }
6044 break;
6045
6046 case GL_TEXTURE_SRGB_DECODE_EXT:
6047 if (!ValidateTextureSRGBDecodeValue(context, params))
6048 {
6049 return false;
6050 }
6051 break;
6052
Luc Ferron1b1a8642018-01-23 15:12:01 -05006053 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6054 {
6055 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6056 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6057 {
6058 return false;
6059 }
6060 }
6061 break;
6062
Till Rathmannb8543632018-10-02 19:46:14 +02006063 case GL_TEXTURE_BORDER_COLOR:
6064 if (!context->getExtensions().textureBorderClamp)
6065 {
Jamie Madille0472f32018-11-27 16:32:45 -05006066 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006067 return false;
6068 }
6069 if (!vectorParams)
6070 {
Jamie Madille0472f32018-11-27 16:32:45 -05006071 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006072 return false;
6073 }
6074 break;
6075
Jamie Madill9696d072017-08-26 23:19:57 -04006076 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006077 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006078 return false;
6079 }
6080
6081 return true;
6082}
6083
Till Rathmannb8543632018-10-02 19:46:14 +02006084template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6085template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6086template bool ValidateSamplerParameterBase(Context *,
6087 GLuint,
6088 GLenum,
6089 GLsizei,
6090 bool,
6091 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006092
6093bool ValidateGetSamplerParameterBase(Context *context,
6094 GLuint sampler,
6095 GLenum pname,
6096 GLsizei *length)
6097{
6098 if (length)
6099 {
6100 *length = 0;
6101 }
6102
6103 if (context->getClientMajorVersion() < 3)
6104 {
Jamie Madille0472f32018-11-27 16:32:45 -05006105 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006106 return false;
6107 }
6108
6109 if (!context->isSampler(sampler))
6110 {
Jamie Madille0472f32018-11-27 16:32:45 -05006111 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006112 return false;
6113 }
6114
6115 switch (pname)
6116 {
6117 case GL_TEXTURE_WRAP_S:
6118 case GL_TEXTURE_WRAP_T:
6119 case GL_TEXTURE_WRAP_R:
6120 case GL_TEXTURE_MIN_FILTER:
6121 case GL_TEXTURE_MAG_FILTER:
6122 case GL_TEXTURE_MIN_LOD:
6123 case GL_TEXTURE_MAX_LOD:
6124 case GL_TEXTURE_COMPARE_MODE:
6125 case GL_TEXTURE_COMPARE_FUNC:
6126 break;
6127
Luc Ferron1b1a8642018-01-23 15:12:01 -05006128 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6129 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6130 {
6131 return false;
6132 }
6133 break;
6134
Jamie Madill9696d072017-08-26 23:19:57 -04006135 case GL_TEXTURE_SRGB_DECODE_EXT:
6136 if (!context->getExtensions().textureSRGBDecode)
6137 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006138 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006139 return false;
6140 }
6141 break;
6142
Till Rathmannb8543632018-10-02 19:46:14 +02006143 case GL_TEXTURE_BORDER_COLOR:
6144 if (!context->getExtensions().textureBorderClamp)
6145 {
Jamie Madille0472f32018-11-27 16:32:45 -05006146 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006147 return false;
6148 }
6149 break;
6150
Jamie Madill9696d072017-08-26 23:19:57 -04006151 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006152 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006153 return false;
6154 }
6155
6156 if (length)
6157 {
Till Rathmannb8543632018-10-02 19:46:14 +02006158 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006159 }
6160 return true;
6161}
6162
6163bool ValidateGetInternalFormativBase(Context *context,
6164 GLenum target,
6165 GLenum internalformat,
6166 GLenum pname,
6167 GLsizei bufSize,
6168 GLsizei *numParams)
6169{
6170 if (numParams)
6171 {
6172 *numParams = 0;
6173 }
6174
6175 if (context->getClientMajorVersion() < 3)
6176 {
Jamie Madille0472f32018-11-27 16:32:45 -05006177 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006178 return false;
6179 }
6180
6181 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006182 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006183 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006184 context->validationError(GL_INVALID_ENUM, kFormatNotRenderable);
Jamie Madill9696d072017-08-26 23:19:57 -04006185 return false;
6186 }
6187
6188 switch (target)
6189 {
6190 case GL_RENDERBUFFER:
6191 break;
6192
6193 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006194 if (context->getClientVersion() < ES_3_1 &&
6195 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006196 {
Jamie Madill610640f2018-11-21 17:28:41 -05006197 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006198 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006199 return false;
6200 }
6201 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006202 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6203 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006204 {
Jamie Madille0472f32018-11-27 16:32:45 -05006205 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006206 return false;
6207 }
6208 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006209 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006210 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006211 return false;
6212 }
6213
6214 if (bufSize < 0)
6215 {
Jamie Madille0472f32018-11-27 16:32:45 -05006216 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006217 return false;
6218 }
6219
6220 GLsizei maxWriteParams = 0;
6221 switch (pname)
6222 {
6223 case GL_NUM_SAMPLE_COUNTS:
6224 maxWriteParams = 1;
6225 break;
6226
6227 case GL_SAMPLES:
6228 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6229 break;
6230
6231 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006232 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006233 return false;
6234 }
6235
6236 if (numParams)
6237 {
6238 // glGetInternalFormativ will not overflow bufSize
6239 *numParams = std::min(bufSize, maxWriteParams);
6240 }
6241
6242 return true;
6243}
6244
Jamie Madille98b1b52018-03-08 09:47:23 -05006245bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6246{
Jamie Madill427064d2018-04-13 16:20:34 -04006247 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006248 {
Jamie Madille0472f32018-11-27 16:32:45 -05006249 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006250 return false;
6251 }
6252 return true;
6253}
6254
Lingfeng Yang038dd532018-03-29 17:31:52 -07006255bool ValidateMultitextureUnit(Context *context, GLenum texture)
6256{
6257 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6258 {
Jamie Madille0472f32018-11-27 16:32:45 -05006259 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006260 return false;
6261 }
6262 return true;
6263}
6264
Olli Etuahod310a432018-08-24 15:40:23 +03006265bool ValidateTexStorageMultisample(Context *context,
6266 TextureType target,
6267 GLsizei samples,
6268 GLint internalFormat,
6269 GLsizei width,
6270 GLsizei height)
6271{
6272 const Caps &caps = context->getCaps();
6273 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6274 static_cast<GLuint>(height) > caps.max2DTextureSize)
6275 {
Jamie Madille0472f32018-11-27 16:32:45 -05006276 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006277 return false;
6278 }
6279
6280 if (samples == 0)
6281 {
Jamie Madille0472f32018-11-27 16:32:45 -05006282 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006283 return false;
6284 }
6285
6286 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6287 if (!formatCaps.textureAttachment)
6288 {
Jamie Madille0472f32018-11-27 16:32:45 -05006289 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006290 return false;
6291 }
6292
6293 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6294 // is one of the unsized base internalformats listed in table 8.11.
6295 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6296 if (formatInfo.internalFormat == GL_NONE)
6297 {
Jamie Madille0472f32018-11-27 16:32:45 -05006298 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006299 return false;
6300 }
6301
6302 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6303 {
Jamie Madille0472f32018-11-27 16:32:45 -05006304 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006305 return false;
6306 }
6307
6308 Texture *texture = context->getTargetTexture(target);
6309 if (!texture || texture->id() == 0)
6310 {
Jamie Madille0472f32018-11-27 16:32:45 -05006311 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006312 return false;
6313 }
6314
6315 if (texture->getImmutableFormat())
6316 {
Jamie Madille0472f32018-11-27 16:32:45 -05006317 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006318 return false;
6319 }
6320 return true;
6321}
6322
Yizhou Jiang7818a852018-09-06 15:02:04 +08006323bool ValidateTexStorage2DMultisampleBase(Context *context,
6324 TextureType target,
6325 GLsizei samples,
6326 GLint internalFormat,
6327 GLsizei width,
6328 GLsizei height)
6329{
6330 if (target != TextureType::_2DMultisample)
6331 {
Jamie Madille0472f32018-11-27 16:32:45 -05006332 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006333 return false;
6334 }
6335
6336 if (width < 1 || height < 1)
6337 {
Jamie Madille0472f32018-11-27 16:32:45 -05006338 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006339 return false;
6340 }
6341
6342 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6343}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006344
6345bool ValidateGetTexLevelParameterBase(Context *context,
6346 TextureTarget target,
6347 GLint level,
6348 GLenum pname,
6349 GLsizei *length)
6350{
6351
6352 if (length)
6353 {
6354 *length = 0;
6355 }
6356
6357 TextureType type = TextureTargetToType(target);
6358
6359 if (!ValidTexLevelDestinationTarget(context, type))
6360 {
Jamie Madille0472f32018-11-27 16:32:45 -05006361 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006362 return false;
6363 }
6364
6365 if (context->getTargetTexture(type) == nullptr)
6366 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006367 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006368 return false;
6369 }
6370
6371 if (!ValidMipLevel(context, type, level))
6372 {
Jamie Madille0472f32018-11-27 16:32:45 -05006373 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006374 return false;
6375 }
6376
6377 switch (pname)
6378 {
6379 case GL_TEXTURE_RED_TYPE:
6380 case GL_TEXTURE_GREEN_TYPE:
6381 case GL_TEXTURE_BLUE_TYPE:
6382 case GL_TEXTURE_ALPHA_TYPE:
6383 case GL_TEXTURE_DEPTH_TYPE:
6384 break;
6385 case GL_TEXTURE_RED_SIZE:
6386 case GL_TEXTURE_GREEN_SIZE:
6387 case GL_TEXTURE_BLUE_SIZE:
6388 case GL_TEXTURE_ALPHA_SIZE:
6389 case GL_TEXTURE_DEPTH_SIZE:
6390 case GL_TEXTURE_STENCIL_SIZE:
6391 case GL_TEXTURE_SHARED_SIZE:
6392 break;
6393 case GL_TEXTURE_INTERNAL_FORMAT:
6394 case GL_TEXTURE_WIDTH:
6395 case GL_TEXTURE_HEIGHT:
6396 case GL_TEXTURE_DEPTH:
6397 break;
6398 case GL_TEXTURE_SAMPLES:
6399 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6400 break;
6401 case GL_TEXTURE_COMPRESSED:
6402 break;
6403 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006404 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006405 return false;
6406 }
6407
6408 if (length)
6409 {
6410 *length = 1;
6411 }
6412 return true;
6413}
Yizhou Jiang7310da32018-11-05 14:40:01 +08006414
6415bool ValidateGetMultisamplefvBase(Context *context, GLenum pname, GLuint index, GLfloat *val)
6416{
6417 if (pname != GL_SAMPLE_POSITION)
6418 {
6419 context->validationError(GL_INVALID_ENUM, kInvalidPname);
6420 return false;
6421 }
6422
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006423 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
Yizhou Jiang7310da32018-11-05 14:40:01 +08006424 GLint samples = framebuffer->getSamples(context);
6425
6426 if (index >= static_cast<GLuint>(samples))
6427 {
6428 context->validationError(GL_INVALID_VALUE, kIndexExceedsSamples);
6429 return false;
6430 }
6431
6432 return true;
6433}
6434
6435bool ValidateSampleMaskiBase(Context *context, GLuint maskNumber, GLbitfield mask)
6436{
6437 if (maskNumber >= context->getCaps().maxSampleMaskWords)
6438 {
6439 context->validationError(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
6440 return false;
6441 }
6442
6443 return true;
6444}
Jamie Madill9fa54ea2019-01-02 18:38:33 -05006445
6446void RecordDrawAttribsError(Context *context)
6447{
6448 // An overflow can happen when adding the offset. Check against a special constant.
6449 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
6450 VertexAttribute::kIntegerOverflow ||
6451 context->getStateCache().getInstancedVertexElementLimit() ==
6452 VertexAttribute::kIntegerOverflow)
6453 {
6454 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
6455 }
6456 else
6457 {
6458 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
6459 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
6460 context->validationError(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
6461 }
6462}
Jamie Madillc29968b2016-01-20 11:17:23 -05006463} // namespace gl