blob: cb1876f1fa84c7bf3f2eb3ccb1773117c480cfcf [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 {
James Darpiniane4109f22018-12-13 16:25:53 -08002730 if (!state.validateSamplerFormats())
2731 {
2732 return kSamplerFormatMismatch;
2733 }
2734
Jamie Madille7d80f32018-08-08 15:49:23 -04002735 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2736 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2737 transformFeedbackObject->buffersBoundForOtherUse())
2738 {
Jamie Madille0472f32018-11-27 16:32:45 -05002739 return kTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002740 }
2741
2742 // Detect rendering feedback loops for WebGL.
2743 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2744 {
Jamie Madille0472f32018-11-27 16:32:45 -05002745 return kFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002746 }
2747
2748 // Detect that the vertex shader input types match the attribute types
2749 if (!ValidateVertexShaderAttributeTypeMatch(context))
2750 {
Jamie Madille0472f32018-11-27 16:32:45 -05002751 return kVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002752 }
2753
2754 // Detect that the color buffer types match the fragment shader output types
2755 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2756 {
Jamie Madille0472f32018-11-27 16:32:45 -05002757 return kDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002758 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002759
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002760 const VertexArray *vao = context->getState().getVertexArray();
Jamie Madill03cb5262018-08-08 15:49:24 -04002761 if (vao->hasTransformFeedbackBindingConflict(context))
2762 {
Jamie Madille0472f32018-11-27 16:32:45 -05002763 return kVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002764 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002765 }
2766 }
2767
Jamie Madillb42162f2018-08-20 12:58:37 -04002768 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002769}
2770
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002771void RecordDrawModeError(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002772{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002773 const State &state = context->getState();
Jamie Madill9b025062018-12-12 15:44:12 -05002774 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
2775 if (curTransformFeedback && curTransformFeedback->isActive() &&
2776 !curTransformFeedback->isPaused())
2777 {
2778 if (!ValidateTransformFeedbackPrimitiveMode(context,
2779 curTransformFeedback->getPrimitiveMode(), mode))
2780 {
2781 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002782 return;
Jamie Madill9b025062018-12-12 15:44:12 -05002783 }
2784 }
2785
Jiawei Shaofccebff2018-03-08 13:51:02 +08002786 const Extensions &extensions = context->getExtensions();
2787
Jamie Madill1aeb1312014-06-20 13:21:25 -04002788 switch (mode)
2789 {
Jamie Madill493f9572018-05-24 19:52:15 -04002790 case PrimitiveMode::Points:
2791 case PrimitiveMode::Lines:
2792 case PrimitiveMode::LineLoop:
2793 case PrimitiveMode::LineStrip:
2794 case PrimitiveMode::Triangles:
2795 case PrimitiveMode::TriangleStrip:
2796 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002797 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002798
Jamie Madill493f9572018-05-24 19:52:15 -04002799 case PrimitiveMode::LinesAdjacency:
2800 case PrimitiveMode::LineStripAdjacency:
2801 case PrimitiveMode::TrianglesAdjacency:
2802 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002803 if (!extensions.geometryShader)
2804 {
Jamie Madille0472f32018-11-27 16:32:45 -05002805 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002806 return;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002807 }
2808 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002809 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002810 context->validationError(GL_INVALID_ENUM, kInvalidDrawMode);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002811 return;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002812 }
2813
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002814 // If we are running GLES1, there is no current program.
2815 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002816 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002817 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002818 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002819
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002820 // Do geometry shader specific validations
2821 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002822 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002823 if (!IsCompatibleDrawModeWithGeometryShader(
2824 mode, program->getGeometryShaderInputPrimitiveType()))
2825 {
Jamie Madill610640f2018-11-21 17:28:41 -05002826 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002827 kIncompatibleDrawModeAgainstGeometryShader);
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002828 return;
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002829 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002830 }
2831 }
2832
Jamie Madill9fa54ea2019-01-02 18:38:33 -05002833 // An error should be recorded.
2834 UNREACHABLE();
Jamie Madillfd716582014-06-06 17:09:04 -04002835}
2836
He Yunchaoced53ae2016-11-29 15:00:51 +08002837bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002838 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002839 GLint first,
2840 GLsizei count,
2841 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002842{
Geoff Lang63c5a592017-09-27 14:08:16 -04002843 if (!context->getExtensions().instancedArrays)
2844 {
Jamie Madille0472f32018-11-27 16:32:45 -05002845 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002846 return false;
2847 }
2848
Corentin Wallez170efbf2017-05-02 13:45:01 -04002849 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002850 {
2851 return false;
2852 }
2853
Corentin Wallez0dc97812017-06-22 14:38:44 -04002854 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002855}
2856
Jamie Madill1e853262018-12-21 09:07:38 -05002857const char *ValidateDrawElementsStates(Context *context)
2858{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002859 const State &state = context->getState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002860
Jamie Madillae6ba9f2018-12-21 23:00:04 -05002861 if (context->getStateCache().isTransformFeedbackActiveUnpaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002862 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002863 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2864 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
Jamie Madill9b025062018-12-12 15:44:12 -05002865 if (!context->getExtensions().geometryShader)
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002866 {
2867 // It is an invalid operation to call DrawElements, DrawRangeElements or
2868 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
2869 // 86)
Jamie Madill1e853262018-12-21 09:07:38 -05002870 return kUnsupportedDrawModeForTransformFeedback;
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002871 }
Jamie Madill250d33f2014-06-06 17:09:03 -04002872 }
2873
Jamie Madillf5c88e72018-12-08 09:56:38 -05002874 const VertexArray *vao = state.getVertexArray();
2875 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
2876
2877 if (elementArrayBuffer)
2878 {
2879 if (context->getExtensions().webglCompatibility)
2880 {
2881 if (elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
2882 {
Jamie Madill1e853262018-12-21 09:07:38 -05002883 return kElementArrayBufferBoundForTransformFeedback;
Jamie Madillf5c88e72018-12-08 09:56:38 -05002884 }
2885 }
2886 else if (elementArrayBuffer->isMapped())
2887 {
2888 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
2889 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the
2890 // WebGL 2.0 API. https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madill1e853262018-12-21 09:07:38 -05002891 return kBufferMapped;
Jamie Madillf5c88e72018-12-08 09:56:38 -05002892 }
2893 }
2894 else
2895 {
2896 // [WebGL 1.0] Section 6.2 No Client Side Arrays
2897 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
2898 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002899 if (!context->getState().areClientArraysEnabled() ||
Jamie Madillf5c88e72018-12-08 09:56:38 -05002900 context->getExtensions().webglCompatibility)
2901 {
Jamie Madill1e853262018-12-21 09:07:38 -05002902 return kMustHaveElementArrayBinding;
Jamie Madillf5c88e72018-12-08 09:56:38 -05002903 }
2904 }
2905
Jamie Madill1e853262018-12-21 09:07:38 -05002906 return nullptr;
Jiajia Qind9671222016-11-29 16:30:31 +08002907}
2908
Jamie Madill5b772312018-03-08 20:28:32 -05002909bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002910 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002911 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05002912 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04002913 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002914 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04002915{
Corentin Wallez0dc97812017-06-22 14:38:44 -04002916 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04002917}
2918
Geoff Lang3edfe032015-09-04 16:38:24 -04002919bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002920 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04002921 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05002922 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04002923 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002924 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002925{
Geoff Lang63c5a592017-09-27 14:08:16 -04002926 if (!context->getExtensions().instancedArrays)
2927 {
Jamie Madille0472f32018-11-27 16:32:45 -05002928 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002929 return false;
2930 }
2931
Corentin Wallez170efbf2017-05-02 13:45:01 -04002932 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002933 {
2934 return false;
2935 }
2936
Corentin Wallez0dc97812017-06-22 14:38:44 -04002937 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002938}
2939
He Yunchaoced53ae2016-11-29 15:00:51 +08002940bool ValidateFramebufferTextureBase(Context *context,
2941 GLenum target,
2942 GLenum attachment,
2943 GLuint texture,
2944 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04002945{
Geoff Lange8afa902017-09-27 15:00:43 -04002946 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04002947 {
Jamie Madille0472f32018-11-27 16:32:45 -05002948 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04002949 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002950 }
2951
2952 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04002953 {
2954 return false;
2955 }
2956
Jamie Madill55ec3b12014-07-03 10:38:57 -04002957 if (texture != 0)
2958 {
Jamie Madill43da7c42018-08-01 11:34:49 -04002959 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04002960
Luc Ferronadcf0ae2018-01-24 08:27:37 -05002961 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04002962 {
Jamie Madille0472f32018-11-27 16:32:45 -05002963 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04002964 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002965 }
2966
2967 if (level < 0)
2968 {
Jamie Madille0472f32018-11-27 16:32:45 -05002969 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002970 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002971 }
2972 }
2973
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002974 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04002975 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04002976
Jamie Madill84115c92015-04-23 15:00:07 -04002977 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04002978 {
Jamie Madille0472f32018-11-27 16:32:45 -05002979 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04002980 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04002981 }
2982
2983 return true;
2984}
2985
Geoff Langb1196682014-07-23 13:47:29 -04002986bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04002987{
2988 if (program == 0)
2989 {
Jamie Madille0472f32018-11-27 16:32:45 -05002990 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04002991 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04002992 }
2993
Jamie Madill43da7c42018-08-01 11:34:49 -04002994 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07002995 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05002996 {
2997 return false;
2998 }
2999
Jamie Madill0063c512014-08-25 15:47:53 -04003000 if (!programObject || !programObject->isLinked())
3001 {
Jamie Madille0472f32018-11-27 16:32:45 -05003002 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003003 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003004 }
3005
Geoff Lang7dd2e102014-11-10 15:19:26 -05003006 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003007 {
Jamie Madille0472f32018-11-27 16:32:45 -05003008 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003009 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003010 }
3011
Jamie Madill0063c512014-08-25 15:47:53 -04003012 return true;
3013}
3014
Geoff Langf41d0ee2016-10-07 13:04:23 -04003015static bool ValidateSizedGetUniform(Context *context,
3016 GLuint program,
3017 GLint location,
3018 GLsizei bufSize,
3019 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003020{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003021 if (length)
3022 {
3023 *length = 0;
3024 }
3025
Jamie Madill78f41802014-08-25 15:47:55 -04003026 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003027 {
Jamie Madill78f41802014-08-25 15:47:55 -04003028 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003029 }
3030
Geoff Langf41d0ee2016-10-07 13:04:23 -04003031 if (bufSize < 0)
3032 {
Jamie Madille0472f32018-11-27 16:32:45 -05003033 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003034 return false;
3035 }
3036
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003037 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003038 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003039
Jamie Madill78f41802014-08-25 15:47:55 -04003040 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003041 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003042 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003043 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003044 {
Jamie Madille0472f32018-11-27 16:32:45 -05003045 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003046 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003047 }
3048
Geoff Langf41d0ee2016-10-07 13:04:23 -04003049 if (length)
3050 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003051 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003052 }
3053
Jamie Madill0063c512014-08-25 15:47:53 -04003054 return true;
3055}
3056
He Yunchaoced53ae2016-11-29 15:00:51 +08003057bool ValidateGetnUniformfvEXT(Context *context,
3058 GLuint program,
3059 GLint location,
3060 GLsizei bufSize,
3061 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003062{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003063 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003064}
3065
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003066bool ValidateGetnUniformfvRobustANGLE(Context *context,
3067 GLuint program,
3068 GLint location,
3069 GLsizei bufSize,
3070 GLsizei *length,
3071 GLfloat *params)
3072{
3073 UNIMPLEMENTED();
3074 return false;
3075}
3076
He Yunchaoced53ae2016-11-29 15:00:51 +08003077bool ValidateGetnUniformivEXT(Context *context,
3078 GLuint program,
3079 GLint location,
3080 GLsizei bufSize,
3081 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003082{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003083 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3084}
3085
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003086bool ValidateGetnUniformivRobustANGLE(Context *context,
3087 GLuint program,
3088 GLint location,
3089 GLsizei bufSize,
3090 GLsizei *length,
3091 GLint *params)
3092{
3093 UNIMPLEMENTED();
3094 return false;
3095}
3096
3097bool ValidateGetnUniformuivRobustANGLE(Context *context,
3098 GLuint program,
3099 GLint location,
3100 GLsizei bufSize,
3101 GLsizei *length,
3102 GLuint *params)
3103{
3104 UNIMPLEMENTED();
3105 return false;
3106}
3107
Geoff Langf41d0ee2016-10-07 13:04:23 -04003108bool ValidateGetUniformfvRobustANGLE(Context *context,
3109 GLuint program,
3110 GLint location,
3111 GLsizei bufSize,
3112 GLsizei *length,
3113 GLfloat *params)
3114{
3115 if (!ValidateRobustEntryPoint(context, bufSize))
3116 {
3117 return false;
3118 }
3119
Brandon Jonesd1049182018-03-28 10:02:20 -07003120 GLsizei writeLength = 0;
3121
Geoff Langf41d0ee2016-10-07 13:04:23 -04003122 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003123 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3124 {
3125 return false;
3126 }
3127
3128 SetRobustLengthParam(length, writeLength);
3129
3130 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003131}
3132
3133bool ValidateGetUniformivRobustANGLE(Context *context,
3134 GLuint program,
3135 GLint location,
3136 GLsizei bufSize,
3137 GLsizei *length,
3138 GLint *params)
3139{
3140 if (!ValidateRobustEntryPoint(context, bufSize))
3141 {
3142 return false;
3143 }
3144
Brandon Jonesd1049182018-03-28 10:02:20 -07003145 GLsizei writeLength = 0;
3146
Geoff Langf41d0ee2016-10-07 13:04:23 -04003147 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003148 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3149 {
3150 return false;
3151 }
3152
3153 SetRobustLengthParam(length, writeLength);
3154
3155 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003156}
3157
3158bool ValidateGetUniformuivRobustANGLE(Context *context,
3159 GLuint program,
3160 GLint location,
3161 GLsizei bufSize,
3162 GLsizei *length,
3163 GLuint *params)
3164{
3165 if (!ValidateRobustEntryPoint(context, bufSize))
3166 {
3167 return false;
3168 }
3169
3170 if (context->getClientMajorVersion() < 3)
3171 {
Jamie Madille0472f32018-11-27 16:32:45 -05003172 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003173 return false;
3174 }
3175
Brandon Jonesd1049182018-03-28 10:02:20 -07003176 GLsizei writeLength = 0;
3177
Geoff Langf41d0ee2016-10-07 13:04:23 -04003178 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003179 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3180 {
3181 return false;
3182 }
3183
3184 SetRobustLengthParam(length, writeLength);
3185
3186 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003187}
3188
He Yunchaoced53ae2016-11-29 15:00:51 +08003189bool ValidateDiscardFramebufferBase(Context *context,
3190 GLenum target,
3191 GLsizei numAttachments,
3192 const GLenum *attachments,
3193 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003194{
3195 if (numAttachments < 0)
3196 {
Jamie Madille0472f32018-11-27 16:32:45 -05003197 context->validationError(GL_INVALID_VALUE, kNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003198 return false;
3199 }
3200
3201 for (GLsizei i = 0; i < numAttachments; ++i)
3202 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003203 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003204 {
3205 if (defaultFramebuffer)
3206 {
Jamie Madille0472f32018-11-27 16:32:45 -05003207 context->validationError(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003208 return false;
3209 }
3210
3211 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3212 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003213 context->validationError(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003214 return false;
3215 }
3216 }
3217 else
3218 {
3219 switch (attachments[i])
3220 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003221 case GL_DEPTH_ATTACHMENT:
3222 case GL_STENCIL_ATTACHMENT:
3223 case GL_DEPTH_STENCIL_ATTACHMENT:
3224 if (defaultFramebuffer)
3225 {
Jamie Madill610640f2018-11-21 17:28:41 -05003226 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003227 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003228 return false;
3229 }
3230 break;
3231 case GL_COLOR:
3232 case GL_DEPTH:
3233 case GL_STENCIL:
3234 if (!defaultFramebuffer)
3235 {
Jamie Madill610640f2018-11-21 17:28:41 -05003236 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003237 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003238 return false;
3239 }
3240 break;
3241 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003242 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003243 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003244 }
3245 }
3246 }
3247
3248 return true;
3249}
3250
Austin Kinross6ee1e782015-05-29 17:05:37 -07003251bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3252{
Jamie Madill007530e2017-12-28 14:27:04 -05003253 if (!context->getExtensions().debugMarker)
3254 {
3255 // The debug marker calls should not set error state
3256 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003257 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003258 return false;
3259 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003260
Jamie Madill007530e2017-12-28 14:27:04 -05003261 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003262 if (length < 0)
3263 {
3264 return false;
3265 }
3266
3267 if (marker == nullptr)
3268 {
3269 return false;
3270 }
3271
3272 return true;
3273}
3274
3275bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3276{
Jamie Madill007530e2017-12-28 14:27:04 -05003277 if (!context->getExtensions().debugMarker)
3278 {
3279 // The debug marker calls should not set error state
3280 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003281 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003282 return false;
3283 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003284
Jamie Madill007530e2017-12-28 14:27:04 -05003285 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003286 if (length < 0)
3287 {
3288 return false;
3289 }
3290
3291 if (length > 0 && marker == nullptr)
3292 {
3293 return false;
3294 }
3295
3296 return true;
3297}
3298
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003299bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003300{
Geoff Langa8406172015-07-21 16:53:39 -04003301 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3302 {
Jamie Madille0472f32018-11-27 16:32:45 -05003303 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003304 return false;
3305 }
3306
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003307 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003308 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003309 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003310 if (!context->getExtensions().eglImage)
3311 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003312 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb66a9092016-05-16 15:59:14 -04003313 }
3314 break;
3315
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003316 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003317 if (!context->getExtensions().eglImageExternal)
3318 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003319 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb66a9092016-05-16 15:59:14 -04003320 }
Geoff Langa8406172015-07-21 16:53:39 -04003321 break;
3322
3323 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003324 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003325 return false;
3326 }
3327
Rafael Cintron05a449a2018-06-20 18:08:04 -07003328 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003329
Jamie Madill61e16b42017-06-19 11:13:23 -04003330 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003331 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003332 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003333 context->validationError(GL_INVALID_VALUE, kInvalidEGLImage);
Geoff Langa8406172015-07-21 16:53:39 -04003334 return false;
3335 }
3336
Jamie Madill007530e2017-12-28 14:27:04 -05003337 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003338 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003339 context->validationError(GL_INVALID_OPERATION, kEGLImageCannotCreate2DMultisampled);
Geoff Langa8406172015-07-21 16:53:39 -04003340 return false;
3341 }
3342
Yuly Novikov2eb54072018-08-22 16:41:26 -04003343 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003344 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003345 context->validationError(GL_INVALID_OPERATION, kEGLImageTextureFormatNotSupported);
Geoff Langa8406172015-07-21 16:53:39 -04003346 return false;
3347 }
3348
Geoff Langdcab33b2015-07-21 13:03:16 -04003349 return true;
3350}
3351
3352bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003353 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003354 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003355{
Geoff Langa8406172015-07-21 16:53:39 -04003356 if (!context->getExtensions().eglImage)
3357 {
Jamie Madille0472f32018-11-27 16:32:45 -05003358 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003359 return false;
3360 }
3361
3362 switch (target)
3363 {
3364 case GL_RENDERBUFFER:
3365 break;
3366
3367 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003368 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003369 return false;
3370 }
3371
Rafael Cintron05a449a2018-06-20 18:08:04 -07003372 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003373
Jamie Madill61e16b42017-06-19 11:13:23 -04003374 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003375 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003376 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003377 context->validationError(GL_INVALID_VALUE, kInvalidEGLImage);
Geoff Langa8406172015-07-21 16:53:39 -04003378 return false;
3379 }
3380
Yuly Novikov2eb54072018-08-22 16:41:26 -04003381 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003382 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003383 context->validationError(GL_INVALID_OPERATION, kEGLImageRenderbufferFormatNotSupported);
Geoff Langa8406172015-07-21 16:53:39 -04003384 return false;
3385 }
3386
Geoff Langdcab33b2015-07-21 13:03:16 -04003387 return true;
3388}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003389
3390bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3391{
Geoff Lang36167ab2015-12-07 10:27:14 -05003392 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003393 {
3394 // The default VAO should always exist
3395 ASSERT(array != 0);
Jamie Madille0472f32018-11-27 16:32:45 -05003396 context->validationError(GL_INVALID_OPERATION, kInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003397 return false;
3398 }
3399
3400 return true;
3401}
3402
Geoff Langc5629752015-12-07 16:29:04 -05003403bool ValidateProgramBinaryBase(Context *context,
3404 GLuint program,
3405 GLenum binaryFormat,
3406 const void *binary,
3407 GLint length)
3408{
3409 Program *programObject = GetValidProgram(context, program);
3410 if (programObject == nullptr)
3411 {
3412 return false;
3413 }
3414
3415 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3416 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3417 programBinaryFormats.end())
3418 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003419 context->validationError(GL_INVALID_ENUM, kInvalidProgramBinaryFormat);
Geoff Langc5629752015-12-07 16:29:04 -05003420 return false;
3421 }
3422
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003423 if (context->hasActiveTransformFeedback(program))
3424 {
3425 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05003426 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackProgramBinary);
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003427 return false;
3428 }
3429
Geoff Langc5629752015-12-07 16:29:04 -05003430 return true;
3431}
3432
3433bool ValidateGetProgramBinaryBase(Context *context,
3434 GLuint program,
3435 GLsizei bufSize,
3436 GLsizei *length,
3437 GLenum *binaryFormat,
3438 void *binary)
3439{
3440 Program *programObject = GetValidProgram(context, program);
3441 if (programObject == nullptr)
3442 {
3443 return false;
3444 }
3445
3446 if (!programObject->isLinked())
3447 {
Jamie Madille0472f32018-11-27 16:32:45 -05003448 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003449 return false;
3450 }
3451
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003452 if (context->getCaps().programBinaryFormats.empty())
3453 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003454 context->validationError(GL_INVALID_OPERATION, kNoProgramBinaryFormats);
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003455 return false;
3456 }
3457
Geoff Langc5629752015-12-07 16:29:04 -05003458 return true;
3459}
Jamie Madillc29968b2016-01-20 11:17:23 -05003460
Jamie Madill5b772312018-03-08 20:28:32 -05003461bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003462{
3463 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003464 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003465 {
Jamie Madille0472f32018-11-27 16:32:45 -05003466 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003467 return false;
3468 }
3469 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3470 {
Jamie Madille0472f32018-11-27 16:32:45 -05003471 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003472 return false;
3473 }
3474
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003475 ASSERT(context->getState().getDrawFramebuffer());
3476 GLuint frameBufferId = context->getState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003477 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3478
3479 // This should come first before the check for the default frame buffer
3480 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3481 // rather than INVALID_OPERATION
3482 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3483 {
3484 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3485
3486 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003487 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3488 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003489 {
3490 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003491 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3492 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3493 // 3.1 is still a bit ambiguous about the error, but future specs are
3494 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madillc3e37312018-11-30 15:25:39 -05003495 context->validationError(GL_INVALID_ENUM, kInvalidDrawBuffer);
Olli Etuaho84c9f592016-03-09 14:37:25 +02003496 return false;
3497 }
3498 else if (bufs[colorAttachment] >= maxColorAttachment)
3499 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003500 context->validationError(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
Jamie Madillc29968b2016-01-20 11:17:23 -05003501 return false;
3502 }
3503 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3504 frameBufferId != 0)
3505 {
3506 // INVALID_OPERATION-GL is bound to buffer and ith argument
3507 // is not COLOR_ATTACHMENTi or NONE
Jamie Madillc3e37312018-11-30 15:25:39 -05003508 context->validationError(GL_INVALID_OPERATION, kInvalidDrawBufferValue);
Jamie Madillc29968b2016-01-20 11:17:23 -05003509 return false;
3510 }
3511 }
3512
3513 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3514 // and n is not 1 or bufs is bound to value other than BACK and NONE
3515 if (frameBufferId == 0)
3516 {
3517 if (n != 1)
3518 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003519 context->validationError(GL_INVALID_OPERATION, kInvalidDrawBufferCountForDefault);
Jamie Madillc29968b2016-01-20 11:17:23 -05003520 return false;
3521 }
3522
3523 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3524 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003525 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferInvalidDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003526 return false;
3527 }
3528 }
3529
3530 return true;
3531}
3532
Geoff Lang496c02d2016-10-20 11:38:11 -07003533bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003534 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003535 GLenum pname,
3536 GLsizei *length,
3537 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003538{
Geoff Lang496c02d2016-10-20 11:38:11 -07003539 if (length)
3540 {
3541 *length = 0;
3542 }
3543
Corentin Walleze4477002017-12-01 14:39:58 -05003544 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003545 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003546 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003547 return false;
3548 }
3549
Geoff Lang496c02d2016-10-20 11:38:11 -07003550 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003551 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003552 case GL_BUFFER_MAP_POINTER:
3553 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003554
Geoff Lang496c02d2016-10-20 11:38:11 -07003555 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003556 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003557 return false;
3558 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003559
3560 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3561 // target bound to zero generate an INVALID_OPERATION error."
3562 // GLES 3.1 section 6.6 explicitly specifies this error.
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003563 if (context->getState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003564 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003565 context->validationError(GL_INVALID_OPERATION, kBufferPointerNotAvailable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003566 return false;
3567 }
3568
Geoff Lang496c02d2016-10-20 11:38:11 -07003569 if (length)
3570 {
3571 *length = 1;
3572 }
3573
Olli Etuaho4f667482016-03-30 15:56:35 +03003574 return true;
3575}
3576
Corentin Wallez336129f2017-10-17 15:55:40 -04003577bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003578{
Corentin Walleze4477002017-12-01 14:39:58 -05003579 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003580 {
Jamie Madille0472f32018-11-27 16:32:45 -05003581 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003582 return false;
3583 }
3584
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003585 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003586
3587 if (buffer == nullptr || !buffer->isMapped())
3588 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003589 context->validationError(GL_INVALID_OPERATION, kBufferNotMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003590 return false;
3591 }
3592
3593 return true;
3594}
3595
3596bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003597 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003598 GLintptr offset,
3599 GLsizeiptr length,
3600 GLbitfield access)
3601{
Corentin Walleze4477002017-12-01 14:39:58 -05003602 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003603 {
Jamie Madille0472f32018-11-27 16:32:45 -05003604 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003605 return false;
3606 }
3607
Brandon Jones6cad5662017-06-14 13:25:13 -07003608 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003609 {
Jamie Madille0472f32018-11-27 16:32:45 -05003610 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003611 return false;
3612 }
3613
3614 if (length < 0)
3615 {
Jamie Madille0472f32018-11-27 16:32:45 -05003616 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003617 return false;
3618 }
3619
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003620 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003621
3622 if (!buffer)
3623 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003624 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003625 return false;
3626 }
3627
3628 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003629 CheckedNumeric<size_t> checkedOffset(offset);
3630 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003631
Jamie Madille2e406c2016-06-02 13:04:10 -04003632 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003633 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003634 context->validationError(GL_INVALID_VALUE, kMapOutOfRange);
Olli Etuaho4f667482016-03-30 15:56:35 +03003635 return false;
3636 }
3637
3638 // Check for invalid bits in the mask
3639 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3640 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3641 GL_MAP_UNSYNCHRONIZED_BIT;
3642
3643 if (access & ~(allAccessBits))
3644 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003645 context->validationError(GL_INVALID_VALUE, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003646 return false;
3647 }
3648
3649 if (length == 0)
3650 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003651 context->validationError(GL_INVALID_OPERATION, kLengthZero);
Olli Etuaho4f667482016-03-30 15:56:35 +03003652 return false;
3653 }
3654
3655 if (buffer->isMapped())
3656 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003657 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003658 return false;
3659 }
3660
3661 // Check for invalid bit combinations
3662 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3663 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003664 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsReadWrite);
Olli Etuaho4f667482016-03-30 15:56:35 +03003665 return false;
3666 }
3667
3668 GLbitfield writeOnlyBits =
3669 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3670
3671 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3672 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003673 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsRead);
Olli Etuaho4f667482016-03-30 15:56:35 +03003674 return false;
3675 }
3676
3677 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3678 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003679 context->validationError(GL_INVALID_OPERATION, kInvalidAccessBitsFlush);
Olli Etuaho4f667482016-03-30 15:56:35 +03003680 return false;
3681 }
Geoff Lang79f71042017-08-14 16:43:43 -04003682
3683 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003684}
3685
3686bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003687 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003688 GLintptr offset,
3689 GLsizeiptr length)
3690{
Brandon Jones6cad5662017-06-14 13:25:13 -07003691 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003692 {
Jamie Madille0472f32018-11-27 16:32:45 -05003693 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003694 return false;
3695 }
3696
3697 if (length < 0)
3698 {
Jamie Madille0472f32018-11-27 16:32:45 -05003699 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003700 return false;
3701 }
3702
Corentin Walleze4477002017-12-01 14:39:58 -05003703 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003704 {
Jamie Madille0472f32018-11-27 16:32:45 -05003705 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003706 return false;
3707 }
3708
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003709 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003710
3711 if (buffer == nullptr)
3712 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003713 context->validationError(GL_INVALID_OPERATION, kInvalidFlushZero);
Olli Etuaho4f667482016-03-30 15:56:35 +03003714 return false;
3715 }
3716
3717 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
3718 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003719 context->validationError(GL_INVALID_OPERATION, kInvalidFlushTarget);
Olli Etuaho4f667482016-03-30 15:56:35 +03003720 return false;
3721 }
3722
3723 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003724 CheckedNumeric<size_t> checkedOffset(offset);
3725 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003726
Jamie Madille2e406c2016-06-02 13:04:10 -04003727 if (!checkedSize.IsValid() ||
3728 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003729 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003730 context->validationError(GL_INVALID_VALUE, kInvalidFlushOutOfRange);
Olli Etuaho4f667482016-03-30 15:56:35 +03003731 return false;
3732 }
3733
3734 return true;
3735}
3736
Olli Etuaho41997e72016-03-10 13:38:39 +02003737bool ValidateGenOrDelete(Context *context, GLint n)
3738{
3739 if (n < 0)
3740 {
Jamie Madille0472f32018-11-27 16:32:45 -05003741 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02003742 return false;
3743 }
3744 return true;
3745}
3746
Jamie Madill5b772312018-03-08 20:28:32 -05003747bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04003748{
3749 if (!context->getExtensions().robustClientMemory)
3750 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003751 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langff5b2d52016-09-07 11:32:23 -04003752 return false;
3753 }
3754
3755 if (bufSize < 0)
3756 {
Jamie Madille0472f32018-11-27 16:32:45 -05003757 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04003758 return false;
3759 }
3760
3761 return true;
3762}
3763
Jamie Madill5b772312018-03-08 20:28:32 -05003764bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04003765{
3766 if (bufSize < numParams)
3767 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003768 context->validationError(GL_INVALID_OPERATION, kInsufficientParams);
Geoff Lang2e43dbb2016-10-14 12:27:35 -04003769 return false;
3770 }
3771
3772 return true;
3773}
3774
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08003775bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04003776 GLenum target,
3777 GLenum attachment,
3778 GLenum pname,
3779 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04003780{
Geoff Lange8afa902017-09-27 15:00:43 -04003781 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04003782 {
Jamie Madille0472f32018-11-27 16:32:45 -05003783 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04003784 return false;
3785 }
3786
3787 int clientVersion = context->getClientMajorVersion();
3788
3789 switch (pname)
3790 {
3791 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3792 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3793 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3794 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3795 break;
3796
Martin Radeve5285d22017-07-14 16:23:53 +03003797 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
3798 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
3799 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
3800 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
3801 if (clientVersion < 3 || !context->getExtensions().multiview)
3802 {
Jamie Madille0472f32018-11-27 16:32:45 -05003803 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03003804 return false;
3805 }
3806 break;
3807
Geoff Langff5b2d52016-09-07 11:32:23 -04003808 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
3809 if (clientVersion < 3 && !context->getExtensions().sRGB)
3810 {
Jamie Madille0472f32018-11-27 16:32:45 -05003811 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04003812 return false;
3813 }
3814 break;
3815
3816 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
3817 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
3818 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
3819 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
3820 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
3821 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
3822 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3823 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
3824 if (clientVersion < 3)
3825 {
Jamie Madille0472f32018-11-27 16:32:45 -05003826 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04003827 return false;
3828 }
3829 break;
3830
Jiawei Shaoa8802472018-05-28 11:17:47 +08003831 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
3832 if (!context->getExtensions().geometryShader)
3833 {
Jamie Madille0472f32018-11-27 16:32:45 -05003834 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08003835 return false;
3836 }
3837 break;
3838
Geoff Langff5b2d52016-09-07 11:32:23 -04003839 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003840 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04003841 return false;
3842 }
3843
3844 // Determine if the attachment is a valid enum
3845 switch (attachment)
3846 {
3847 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04003848 case GL_DEPTH:
3849 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04003850 if (clientVersion < 3)
3851 {
Jamie Madille0472f32018-11-27 16:32:45 -05003852 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003853 return false;
3854 }
3855 break;
3856
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08003857 case GL_DEPTH_STENCIL_ATTACHMENT:
3858 if (clientVersion < 3 && !context->isWebGL1())
3859 {
Jamie Madille0472f32018-11-27 16:32:45 -05003860 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08003861 return false;
3862 }
3863 break;
3864
Geoff Langfa125c92017-10-24 13:01:46 -04003865 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04003866 case GL_DEPTH_ATTACHMENT:
3867 case GL_STENCIL_ATTACHMENT:
3868 break;
3869
3870 default:
Geoff Langfa125c92017-10-24 13:01:46 -04003871 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
3872 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04003873 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
3874 {
Jamie Madille0472f32018-11-27 16:32:45 -05003875 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003876 return false;
3877 }
3878 break;
3879 }
3880
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003881 const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
Geoff Langff5b2d52016-09-07 11:32:23 -04003882 ASSERT(framebuffer);
3883
3884 if (framebuffer->id() == 0)
3885 {
3886 if (clientVersion < 3)
3887 {
Jamie Madille0472f32018-11-27 16:32:45 -05003888 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04003889 return false;
3890 }
3891
3892 switch (attachment)
3893 {
3894 case GL_BACK:
3895 case GL_DEPTH:
3896 case GL_STENCIL:
3897 break;
3898
3899 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003900 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003901 return false;
3902 }
3903 }
3904 else
3905 {
3906 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
3907 {
3908 // Valid attachment query
3909 }
3910 else
3911 {
3912 switch (attachment)
3913 {
3914 case GL_DEPTH_ATTACHMENT:
3915 case GL_STENCIL_ATTACHMENT:
3916 break;
3917
3918 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08003919 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04003920 {
Jamie Madille0472f32018-11-27 16:32:45 -05003921 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003922 return false;
3923 }
3924 break;
3925
3926 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003927 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003928 return false;
3929 }
3930 }
3931 }
3932
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08003933 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003934 if (attachmentObject)
3935 {
3936 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
3937 attachmentObject->type() == GL_TEXTURE ||
3938 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
3939
3940 switch (pname)
3941 {
3942 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3943 if (attachmentObject->type() != GL_RENDERBUFFER &&
3944 attachmentObject->type() != GL_TEXTURE)
3945 {
Jamie Madille0472f32018-11-27 16:32:45 -05003946 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003947 return false;
3948 }
3949 break;
3950
3951 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
3952 if (attachmentObject->type() != GL_TEXTURE)
3953 {
Jamie Madille0472f32018-11-27 16:32:45 -05003954 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003955 return false;
3956 }
3957 break;
3958
3959 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
3960 if (attachmentObject->type() != GL_TEXTURE)
3961 {
Jamie Madille0472f32018-11-27 16:32:45 -05003962 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003963 return false;
3964 }
3965 break;
3966
3967 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
3968 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
3969 {
Jamie Madille0472f32018-11-27 16:32:45 -05003970 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003971 return false;
3972 }
3973 break;
3974
3975 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
3976 if (attachmentObject->type() != GL_TEXTURE)
3977 {
Jamie Madille0472f32018-11-27 16:32:45 -05003978 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04003979 return false;
3980 }
3981 break;
3982
3983 default:
3984 break;
3985 }
3986 }
3987 else
3988 {
3989 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3990 // is NONE, then querying any other pname will generate INVALID_ENUM.
3991
3992 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
3993 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3994 // INVALID_OPERATION for all other pnames
3995
3996 switch (pname)
3997 {
3998 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3999 break;
4000
4001 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4002 if (clientVersion < 3)
4003 {
Jamie Madill610640f2018-11-21 17:28:41 -05004004 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004005 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004006 return false;
4007 }
4008 break;
4009
4010 default:
4011 if (clientVersion < 3)
4012 {
Jamie Madill610640f2018-11-21 17:28:41 -05004013 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004014 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004015 return false;
4016 }
4017 else
4018 {
Jamie Madill610640f2018-11-21 17:28:41 -05004019 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05004020 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004021 return false;
4022 }
4023 }
4024 }
4025
Martin Radeve5285d22017-07-14 16:23:53 +03004026 if (numParams)
4027 {
4028 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4029 {
4030 // Only when the viewport offsets are queried we can have a varying number of output
4031 // parameters.
4032 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4033 *numParams = numViews * 2;
4034 }
4035 else
4036 {
4037 // For all other queries we can have only one output parameter.
4038 *numParams = 1;
4039 }
4040 }
4041
Geoff Langff5b2d52016-09-07 11:32:23 -04004042 return true;
4043}
4044
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004045bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004046 GLenum target,
4047 GLenum attachment,
4048 GLenum pname,
4049 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004050 GLsizei *length,
4051 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004052{
4053 if (!ValidateRobustEntryPoint(context, bufSize))
4054 {
4055 return false;
4056 }
4057
Brandon Jonesd1049182018-03-28 10:02:20 -07004058 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004059 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004060 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004061 {
4062 return false;
4063 }
4064
Brandon Jonesd1049182018-03-28 10:02:20 -07004065 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004066 {
4067 return false;
4068 }
4069
Brandon Jonesd1049182018-03-28 10:02:20 -07004070 SetRobustLengthParam(length, numParams);
4071
Geoff Langff5b2d52016-09-07 11:32:23 -04004072 return true;
4073}
4074
Jamie Madill5b772312018-03-08 20:28:32 -05004075bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004076 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004077 GLenum pname,
4078 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004079 GLsizei *length,
4080 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004081{
4082 if (!ValidateRobustEntryPoint(context, bufSize))
4083 {
4084 return false;
4085 }
4086
Brandon Jonesd1049182018-03-28 10:02:20 -07004087 GLsizei numParams = 0;
4088
4089 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004090 {
4091 return false;
4092 }
4093
Brandon Jonesd1049182018-03-28 10:02:20 -07004094 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004095 {
4096 return false;
4097 }
4098
Brandon Jonesd1049182018-03-28 10:02:20 -07004099 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004100 return true;
4101}
4102
Jamie Madill5b772312018-03-08 20:28:32 -05004103bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004104 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004105 GLenum pname,
4106 GLsizei bufSize,
4107 GLsizei *length,
4108 GLint64 *params)
4109{
Brandon Jonesd1049182018-03-28 10:02:20 -07004110 GLsizei numParams = 0;
4111
Geoff Langebebe1c2016-10-14 12:01:31 -04004112 if (!ValidateRobustEntryPoint(context, bufSize))
4113 {
4114 return false;
4115 }
4116
Brandon Jonesd1049182018-03-28 10:02:20 -07004117 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004118 {
4119 return false;
4120 }
4121
Brandon Jonesd1049182018-03-28 10:02:20 -07004122 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004123 {
4124 return false;
4125 }
4126
Brandon Jonesd1049182018-03-28 10:02:20 -07004127 SetRobustLengthParam(length, numParams);
4128
Geoff Langff5b2d52016-09-07 11:32:23 -04004129 return true;
4130}
4131
Jamie Madill5b772312018-03-08 20:28:32 -05004132bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004133{
4134 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004135 if (numParams)
4136 {
4137 *numParams = 1;
4138 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004139
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004140 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4141 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4142 ? GetValidProgramNoResolve(context, program)
4143 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004144 if (!programObject)
4145 {
4146 return false;
4147 }
4148
4149 switch (pname)
4150 {
4151 case GL_DELETE_STATUS:
4152 case GL_LINK_STATUS:
4153 case GL_VALIDATE_STATUS:
4154 case GL_INFO_LOG_LENGTH:
4155 case GL_ATTACHED_SHADERS:
4156 case GL_ACTIVE_ATTRIBUTES:
4157 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4158 case GL_ACTIVE_UNIFORMS:
4159 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4160 break;
4161
4162 case GL_PROGRAM_BINARY_LENGTH:
4163 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4164 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004165 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004166 return false;
4167 }
4168 break;
4169
4170 case GL_ACTIVE_UNIFORM_BLOCKS:
4171 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4172 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4173 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4174 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4175 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4176 if (context->getClientMajorVersion() < 3)
4177 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004178 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Geoff Langff5b2d52016-09-07 11:32:23 -04004179 return false;
4180 }
4181 break;
4182
Yunchao He61afff12017-03-14 15:34:03 +08004183 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004184 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004185 if (context->getClientVersion() < Version(3, 1))
4186 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004187 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao He61afff12017-03-14 15:34:03 +08004188 return false;
4189 }
4190 break;
4191
Jiawei Shao6ae51612018-02-23 14:03:25 +08004192 case GL_COMPUTE_WORK_GROUP_SIZE:
4193 if (context->getClientVersion() < Version(3, 1))
4194 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004195 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004196 return false;
4197 }
4198
4199 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4200 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4201 // program which has not been linked successfully, or which does not contain objects to
4202 // form a compute shader.
4203 if (!programObject->isLinked())
4204 {
Jamie Madille0472f32018-11-27 16:32:45 -05004205 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004206 return false;
4207 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004208 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004209 {
Jamie Madille0472f32018-11-27 16:32:45 -05004210 context->validationError(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004211 return false;
4212 }
4213 break;
4214
Jiawei Shao447bfac2018-03-14 14:23:40 +08004215 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4216 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4217 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4218 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4219 if (!context->getExtensions().geometryShader)
4220 {
Jamie Madille0472f32018-11-27 16:32:45 -05004221 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004222 return false;
4223 }
4224
4225 // [EXT_geometry_shader] Chapter 7.12
4226 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4227 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4228 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4229 // successfully, or which does not contain objects to form a geometry shader.
4230 if (!programObject->isLinked())
4231 {
Jamie Madille0472f32018-11-27 16:32:45 -05004232 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004233 return false;
4234 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004235 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004236 {
Jamie Madille0472f32018-11-27 16:32:45 -05004237 context->validationError(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004238 return false;
4239 }
4240 break;
4241
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004242 case GL_COMPLETION_STATUS_KHR:
4243 if (!context->getExtensions().parallelShaderCompile)
4244 {
Jamie Madille0472f32018-11-27 16:32:45 -05004245 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004246 return false;
4247 }
4248 break;
4249
Geoff Langff5b2d52016-09-07 11:32:23 -04004250 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004251 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004252 return false;
4253 }
4254
4255 return true;
4256}
4257
4258bool ValidateGetProgramivRobustANGLE(Context *context,
4259 GLuint program,
4260 GLenum pname,
4261 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004262 GLsizei *length,
4263 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004264{
4265 if (!ValidateRobustEntryPoint(context, bufSize))
4266 {
4267 return false;
4268 }
4269
Brandon Jonesd1049182018-03-28 10:02:20 -07004270 GLsizei numParams = 0;
4271
4272 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004273 {
4274 return false;
4275 }
4276
Brandon Jonesd1049182018-03-28 10:02:20 -07004277 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004278 {
4279 return false;
4280 }
4281
Brandon Jonesd1049182018-03-28 10:02:20 -07004282 SetRobustLengthParam(length, numParams);
4283
Geoff Langff5b2d52016-09-07 11:32:23 -04004284 return true;
4285}
4286
Geoff Lang740d9022016-10-07 11:20:52 -04004287bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4288 GLenum target,
4289 GLenum pname,
4290 GLsizei bufSize,
4291 GLsizei *length,
4292 GLint *params)
4293{
4294 if (!ValidateRobustEntryPoint(context, bufSize))
4295 {
4296 return false;
4297 }
4298
Brandon Jonesd1049182018-03-28 10:02:20 -07004299 GLsizei numParams = 0;
4300
4301 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004302 {
4303 return false;
4304 }
4305
Brandon Jonesd1049182018-03-28 10:02:20 -07004306 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004307 {
4308 return false;
4309 }
4310
Brandon Jonesd1049182018-03-28 10:02:20 -07004311 SetRobustLengthParam(length, numParams);
4312
Geoff Lang740d9022016-10-07 11:20:52 -04004313 return true;
4314}
4315
Geoff Langd7d0ed32016-10-07 11:33:51 -04004316bool ValidateGetShaderivRobustANGLE(Context *context,
4317 GLuint shader,
4318 GLenum pname,
4319 GLsizei bufSize,
4320 GLsizei *length,
4321 GLint *params)
4322{
4323 if (!ValidateRobustEntryPoint(context, bufSize))
4324 {
4325 return false;
4326 }
4327
Brandon Jonesd1049182018-03-28 10:02:20 -07004328 GLsizei numParams = 0;
4329
4330 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004331 {
4332 return false;
4333 }
4334
Brandon Jonesd1049182018-03-28 10:02:20 -07004335 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004336 {
4337 return false;
4338 }
4339
Brandon Jonesd1049182018-03-28 10:02:20 -07004340 SetRobustLengthParam(length, numParams);
4341
Geoff Langd7d0ed32016-10-07 11:33:51 -04004342 return true;
4343}
4344
Geoff Langc1984ed2016-10-07 12:41:00 -04004345bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004346 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004347 GLenum pname,
4348 GLsizei bufSize,
4349 GLsizei *length,
4350 GLfloat *params)
4351{
4352 if (!ValidateRobustEntryPoint(context, bufSize))
4353 {
4354 return false;
4355 }
4356
Brandon Jonesd1049182018-03-28 10:02:20 -07004357 GLsizei numParams = 0;
4358
4359 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004360 {
4361 return false;
4362 }
4363
Brandon Jonesd1049182018-03-28 10:02:20 -07004364 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004365 {
4366 return false;
4367 }
4368
Brandon Jonesd1049182018-03-28 10:02:20 -07004369 SetRobustLengthParam(length, numParams);
4370
Geoff Langc1984ed2016-10-07 12:41:00 -04004371 return true;
4372}
4373
Geoff Langc1984ed2016-10-07 12:41:00 -04004374bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004375 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004376 GLenum pname,
4377 GLsizei bufSize,
4378 GLsizei *length,
4379 GLint *params)
4380{
Brandon Jonesd1049182018-03-28 10:02:20 -07004381
Geoff Langc1984ed2016-10-07 12:41:00 -04004382 if (!ValidateRobustEntryPoint(context, bufSize))
4383 {
4384 return false;
4385 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004386 GLsizei numParams = 0;
4387 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004388 {
4389 return false;
4390 }
4391
Brandon Jonesd1049182018-03-28 10:02:20 -07004392 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004393 {
4394 return false;
4395 }
4396
Brandon Jonesd1049182018-03-28 10:02:20 -07004397 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004398 return true;
4399}
4400
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004401bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4402 TextureType target,
4403 GLenum pname,
4404 GLsizei bufSize,
4405 GLsizei *length,
4406 GLint *params)
4407{
4408 UNIMPLEMENTED();
4409 return false;
4410}
4411
4412bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4413 TextureType target,
4414 GLenum pname,
4415 GLsizei bufSize,
4416 GLsizei *length,
4417 GLuint *params)
4418{
4419 UNIMPLEMENTED();
4420 return false;
4421}
4422
Geoff Langc1984ed2016-10-07 12:41:00 -04004423bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004424 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004425 GLenum pname,
4426 GLsizei bufSize,
4427 const GLfloat *params)
4428{
4429 if (!ValidateRobustEntryPoint(context, bufSize))
4430 {
4431 return false;
4432 }
4433
Till Rathmannb8543632018-10-02 19:46:14 +02004434 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004435}
4436
Geoff Langc1984ed2016-10-07 12:41:00 -04004437bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004438 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004439 GLenum pname,
4440 GLsizei bufSize,
4441 const GLint *params)
4442{
4443 if (!ValidateRobustEntryPoint(context, bufSize))
4444 {
4445 return false;
4446 }
4447
Till Rathmannb8543632018-10-02 19:46:14 +02004448 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004449}
4450
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004451bool ValidateTexParameterIivRobustANGLE(Context *context,
4452 TextureType target,
4453 GLenum pname,
4454 GLsizei bufSize,
4455 const GLint *params)
4456{
4457 UNIMPLEMENTED();
4458 return false;
4459}
4460
4461bool ValidateTexParameterIuivRobustANGLE(Context *context,
4462 TextureType target,
4463 GLenum pname,
4464 GLsizei bufSize,
4465 const GLuint *params)
4466{
4467 UNIMPLEMENTED();
4468 return false;
4469}
4470
Geoff Langc1984ed2016-10-07 12:41:00 -04004471bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4472 GLuint sampler,
4473 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004474 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004475 GLsizei *length,
4476 GLfloat *params)
4477{
4478 if (!ValidateRobustEntryPoint(context, bufSize))
4479 {
4480 return false;
4481 }
4482
Brandon Jonesd1049182018-03-28 10:02:20 -07004483 GLsizei numParams = 0;
4484
4485 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004486 {
4487 return false;
4488 }
4489
Brandon Jonesd1049182018-03-28 10:02:20 -07004490 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004491 {
4492 return false;
4493 }
4494
Brandon Jonesd1049182018-03-28 10:02:20 -07004495 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004496 return true;
4497}
4498
Geoff Langc1984ed2016-10-07 12:41:00 -04004499bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4500 GLuint sampler,
4501 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004502 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004503 GLsizei *length,
4504 GLint *params)
4505{
4506 if (!ValidateRobustEntryPoint(context, bufSize))
4507 {
4508 return false;
4509 }
4510
Brandon Jonesd1049182018-03-28 10:02:20 -07004511 GLsizei numParams = 0;
4512
4513 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004514 {
4515 return false;
4516 }
4517
Brandon Jonesd1049182018-03-28 10:02:20 -07004518 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004519 {
4520 return false;
4521 }
4522
Brandon Jonesd1049182018-03-28 10:02:20 -07004523 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004524 return true;
4525}
4526
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004527bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4528 GLuint sampler,
4529 GLenum pname,
4530 GLsizei bufSize,
4531 GLsizei *length,
4532 GLint *params)
4533{
4534 UNIMPLEMENTED();
4535 return false;
4536}
4537
4538bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4539 GLuint sampler,
4540 GLenum pname,
4541 GLsizei bufSize,
4542 GLsizei *length,
4543 GLuint *params)
4544{
4545 UNIMPLEMENTED();
4546 return false;
4547}
4548
Geoff Langc1984ed2016-10-07 12:41:00 -04004549bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4550 GLuint sampler,
4551 GLenum pname,
4552 GLsizei bufSize,
4553 const GLfloat *params)
4554{
4555 if (!ValidateRobustEntryPoint(context, bufSize))
4556 {
4557 return false;
4558 }
4559
Till Rathmannb8543632018-10-02 19:46:14 +02004560 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004561}
4562
Geoff Langc1984ed2016-10-07 12:41:00 -04004563bool ValidateSamplerParameterivRobustANGLE(Context *context,
4564 GLuint sampler,
4565 GLenum pname,
4566 GLsizei bufSize,
4567 const GLint *params)
4568{
4569 if (!ValidateRobustEntryPoint(context, bufSize))
4570 {
4571 return false;
4572 }
4573
Till Rathmannb8543632018-10-02 19:46:14 +02004574 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004575}
4576
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004577bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4578 GLuint sampler,
4579 GLenum pname,
4580 GLsizei bufSize,
4581 const GLint *param)
4582{
4583 UNIMPLEMENTED();
4584 return false;
4585}
4586
4587bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4588 GLuint sampler,
4589 GLenum pname,
4590 GLsizei bufSize,
4591 const GLuint *param)
4592{
4593 UNIMPLEMENTED();
4594 return false;
4595}
4596
Geoff Lang0b031062016-10-13 14:30:04 -04004597bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4598 GLuint index,
4599 GLenum pname,
4600 GLsizei bufSize,
4601 GLsizei *length,
4602 GLfloat *params)
4603{
4604 if (!ValidateRobustEntryPoint(context, bufSize))
4605 {
4606 return false;
4607 }
4608
Brandon Jonesd1049182018-03-28 10:02:20 -07004609 GLsizei writeLength = 0;
4610
4611 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004612 {
4613 return false;
4614 }
4615
Brandon Jonesd1049182018-03-28 10:02:20 -07004616 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004617 {
4618 return false;
4619 }
4620
Brandon Jonesd1049182018-03-28 10:02:20 -07004621 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004622 return true;
4623}
4624
Geoff Lang0b031062016-10-13 14:30:04 -04004625bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4626 GLuint index,
4627 GLenum pname,
4628 GLsizei bufSize,
4629 GLsizei *length,
4630 GLint *params)
4631{
4632 if (!ValidateRobustEntryPoint(context, bufSize))
4633 {
4634 return false;
4635 }
4636
Brandon Jonesd1049182018-03-28 10:02:20 -07004637 GLsizei writeLength = 0;
4638
4639 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004640 {
4641 return false;
4642 }
4643
Brandon Jonesd1049182018-03-28 10:02:20 -07004644 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004645 {
4646 return false;
4647 }
4648
Brandon Jonesd1049182018-03-28 10:02:20 -07004649 SetRobustLengthParam(length, writeLength);
4650
Geoff Lang0b031062016-10-13 14:30:04 -04004651 return true;
4652}
4653
Geoff Lang0b031062016-10-13 14:30:04 -04004654bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4655 GLuint index,
4656 GLenum pname,
4657 GLsizei bufSize,
4658 GLsizei *length,
4659 void **pointer)
4660{
4661 if (!ValidateRobustEntryPoint(context, bufSize))
4662 {
4663 return false;
4664 }
4665
Brandon Jonesd1049182018-03-28 10:02:20 -07004666 GLsizei writeLength = 0;
4667
4668 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004669 {
4670 return false;
4671 }
4672
Brandon Jonesd1049182018-03-28 10:02:20 -07004673 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004674 {
4675 return false;
4676 }
4677
Brandon Jonesd1049182018-03-28 10:02:20 -07004678 SetRobustLengthParam(length, writeLength);
4679
Geoff Lang0b031062016-10-13 14:30:04 -04004680 return true;
4681}
4682
Geoff Lang0b031062016-10-13 14:30:04 -04004683bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4684 GLuint index,
4685 GLenum pname,
4686 GLsizei bufSize,
4687 GLsizei *length,
4688 GLint *params)
4689{
4690 if (!ValidateRobustEntryPoint(context, bufSize))
4691 {
4692 return false;
4693 }
4694
Brandon Jonesd1049182018-03-28 10:02:20 -07004695 GLsizei writeLength = 0;
4696
4697 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004698 {
4699 return false;
4700 }
4701
Brandon Jonesd1049182018-03-28 10:02:20 -07004702 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004703 {
4704 return false;
4705 }
4706
Brandon Jonesd1049182018-03-28 10:02:20 -07004707 SetRobustLengthParam(length, writeLength);
4708
Geoff Lang0b031062016-10-13 14:30:04 -04004709 return true;
4710}
4711
Geoff Lang0b031062016-10-13 14:30:04 -04004712bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
4713 GLuint index,
4714 GLenum pname,
4715 GLsizei bufSize,
4716 GLsizei *length,
4717 GLuint *params)
4718{
4719 if (!ValidateRobustEntryPoint(context, bufSize))
4720 {
4721 return false;
4722 }
4723
Brandon Jonesd1049182018-03-28 10:02:20 -07004724 GLsizei writeLength = 0;
4725
4726 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004727 {
4728 return false;
4729 }
4730
Brandon Jonesd1049182018-03-28 10:02:20 -07004731 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004732 {
4733 return false;
4734 }
4735
Brandon Jonesd1049182018-03-28 10:02:20 -07004736 SetRobustLengthParam(length, writeLength);
4737
Geoff Lang0b031062016-10-13 14:30:04 -04004738 return true;
4739}
4740
Geoff Lang6899b872016-10-14 11:30:13 -04004741bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
4742 GLuint program,
4743 GLuint uniformBlockIndex,
4744 GLenum pname,
4745 GLsizei bufSize,
4746 GLsizei *length,
4747 GLint *params)
4748{
4749 if (!ValidateRobustEntryPoint(context, bufSize))
4750 {
4751 return false;
4752 }
4753
Brandon Jonesd1049182018-03-28 10:02:20 -07004754 GLsizei writeLength = 0;
4755
4756 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
4757 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04004758 {
4759 return false;
4760 }
4761
Brandon Jonesd1049182018-03-28 10:02:20 -07004762 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04004763 {
4764 return false;
4765 }
4766
Brandon Jonesd1049182018-03-28 10:02:20 -07004767 SetRobustLengthParam(length, writeLength);
4768
Geoff Lang6899b872016-10-14 11:30:13 -04004769 return true;
4770}
4771
Brandon Jones416aaf92018-04-10 08:10:16 -07004772bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07004773 GLenum target,
4774 GLenum internalformat,
4775 GLenum pname,
4776 GLsizei bufSize,
4777 GLsizei *length,
4778 GLint *params)
4779{
4780 if (!ValidateRobustEntryPoint(context, bufSize))
4781 {
4782 return false;
4783 }
4784
Brandon Jonesd1049182018-03-28 10:02:20 -07004785 GLsizei numParams = 0;
4786
4787 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
4788 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07004789 {
4790 return false;
4791 }
4792
Brandon Jonesd1049182018-03-28 10:02:20 -07004793 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07004794 {
4795 return false;
4796 }
4797
Brandon Jonesd1049182018-03-28 10:02:20 -07004798 SetRobustLengthParam(length, numParams);
4799
Geoff Lang0a9661f2016-10-20 10:59:20 -07004800 return true;
4801}
4802
Jamie Madill5b772312018-03-08 20:28:32 -05004803bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08004804 GLuint attribIndex,
4805 GLint size,
4806 GLenum type,
4807 GLboolean pureInteger)
4808{
4809 const Caps &caps = context->getCaps();
4810 if (attribIndex >= caps.maxVertexAttributes)
4811 {
Jamie Madille0472f32018-11-27 16:32:45 -05004812 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08004813 return false;
4814 }
4815
4816 if (size < 1 || size > 4)
4817 {
Jamie Madille0472f32018-11-27 16:32:45 -05004818 context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04004819 return false;
Shao80957d92017-02-20 21:25:59 +08004820 }
4821
4822 switch (type)
4823 {
4824 case GL_BYTE:
4825 case GL_UNSIGNED_BYTE:
4826 case GL_SHORT:
4827 case GL_UNSIGNED_SHORT:
4828 break;
4829
4830 case GL_INT:
4831 case GL_UNSIGNED_INT:
4832 if (context->getClientMajorVersion() < 3)
4833 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004834 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004835 return false;
4836 }
4837 break;
4838
4839 case GL_FIXED:
4840 case GL_FLOAT:
4841 if (pureInteger)
4842 {
Jamie Madille0472f32018-11-27 16:32:45 -05004843 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004844 return false;
4845 }
4846 break;
4847
4848 case GL_HALF_FLOAT:
4849 if (context->getClientMajorVersion() < 3)
4850 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004851 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004852 return false;
4853 }
4854 if (pureInteger)
4855 {
Jamie Madille0472f32018-11-27 16:32:45 -05004856 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004857 return false;
4858 }
4859 break;
4860
4861 case GL_INT_2_10_10_10_REV:
4862 case GL_UNSIGNED_INT_2_10_10_10_REV:
4863 if (context->getClientMajorVersion() < 3)
4864 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004865 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004866 return false;
4867 }
4868 if (pureInteger)
4869 {
Jamie Madille0472f32018-11-27 16:32:45 -05004870 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004871 return false;
4872 }
4873 if (size != 4)
4874 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004875 context->validationError(GL_INVALID_OPERATION, kInvalidVertexAttribSize2101010);
Shao80957d92017-02-20 21:25:59 +08004876 return false;
4877 }
4878 break;
4879
4880 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004881 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08004882 return false;
4883 }
4884
4885 return true;
4886}
4887
Geoff Lang76e65652017-03-27 14:58:02 -04004888// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
4889// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
4890// specified clear value and the type of a buffer that is being cleared generates an
4891// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05004892bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04004893 GLint drawbuffer,
4894 const GLenum *validComponentTypes,
4895 size_t validComponentTypeCount)
4896{
4897 const FramebufferAttachment *attachment =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004898 context->getState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
Geoff Lang76e65652017-03-27 14:58:02 -04004899 if (attachment)
4900 {
4901 GLenum componentType = attachment->getFormat().info->componentType;
4902 const GLenum *end = validComponentTypes + validComponentTypeCount;
4903 if (std::find(validComponentTypes, end, componentType) == end)
4904 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004905 context->validationError(GL_INVALID_OPERATION, kNoDefinedClearConversion);
Geoff Lang76e65652017-03-27 14:58:02 -04004906 return false;
4907 }
4908 }
4909
4910 return true;
4911}
4912
Jamie Madill5b772312018-03-08 20:28:32 -05004913bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04004914{
4915 if (!ValidateRobustEntryPoint(context, dataSize))
4916 {
4917 return false;
4918 }
4919
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004920 Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04004921 if (pixelUnpackBuffer == nullptr)
4922 {
4923 if (dataSize < imageSize)
4924 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004925 context->validationError(GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
Corentin Wallezb2931602017-04-11 15:58:57 -04004926 }
4927 }
4928 return true;
4929}
4930
Jamie Madill5b772312018-03-08 20:28:32 -05004931bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004932 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04004933 GLenum pname,
4934 bool pointerVersion,
4935 GLsizei *numParams)
4936{
4937 if (numParams)
4938 {
4939 *numParams = 0;
4940 }
4941
Corentin Walleze4477002017-12-01 14:39:58 -05004942 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04004943 {
Jamie Madille0472f32018-11-27 16:32:45 -05004944 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04004945 return false;
4946 }
4947
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004948 const Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04004949 if (!buffer)
4950 {
4951 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05004952 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04004953 return false;
4954 }
4955
4956 const Extensions &extensions = context->getExtensions();
4957
4958 switch (pname)
4959 {
4960 case GL_BUFFER_USAGE:
4961 case GL_BUFFER_SIZE:
4962 break;
4963
4964 case GL_BUFFER_ACCESS_OES:
4965 if (!extensions.mapBuffer)
4966 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004967 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004968 return false;
4969 }
4970 break;
4971
4972 case GL_BUFFER_MAPPED:
4973 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
4974 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
4975 !extensions.mapBufferRange)
4976 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004977 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004978 return false;
4979 }
4980 break;
4981
4982 case GL_BUFFER_MAP_POINTER:
4983 if (!pointerVersion)
4984 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004985 context->validationError(GL_INVALID_ENUM, kInvalidMapPointerQuery);
Jamie Madillbe849e42017-05-02 15:49:00 -04004986 return false;
4987 }
4988 break;
4989
4990 case GL_BUFFER_ACCESS_FLAGS:
4991 case GL_BUFFER_MAP_OFFSET:
4992 case GL_BUFFER_MAP_LENGTH:
4993 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
4994 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004995 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004996 return false;
4997 }
4998 break;
4999
Geoff Lang79b91402018-10-04 15:11:30 -04005000 case GL_MEMORY_SIZE_ANGLE:
5001 if (!context->getExtensions().memorySize)
5002 {
Jamie Madille0472f32018-11-27 16:32:45 -05005003 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005004 return false;
5005 }
5006 break;
5007
Jamie Madillbe849e42017-05-02 15:49:00 -04005008 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005009 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005010 return false;
5011 }
5012
5013 // All buffer parameter queries return one value.
5014 if (numParams)
5015 {
5016 *numParams = 1;
5017 }
5018
5019 return true;
5020}
5021
5022bool ValidateGetRenderbufferParameterivBase(Context *context,
5023 GLenum target,
5024 GLenum pname,
5025 GLsizei *length)
5026{
5027 if (length)
5028 {
5029 *length = 0;
5030 }
5031
5032 if (target != GL_RENDERBUFFER)
5033 {
Jamie Madille0472f32018-11-27 16:32:45 -05005034 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005035 return false;
5036 }
5037
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005038 Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005039 if (renderbuffer == nullptr)
5040 {
Jamie Madille0472f32018-11-27 16:32:45 -05005041 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005042 return false;
5043 }
5044
5045 switch (pname)
5046 {
5047 case GL_RENDERBUFFER_WIDTH:
5048 case GL_RENDERBUFFER_HEIGHT:
5049 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5050 case GL_RENDERBUFFER_RED_SIZE:
5051 case GL_RENDERBUFFER_GREEN_SIZE:
5052 case GL_RENDERBUFFER_BLUE_SIZE:
5053 case GL_RENDERBUFFER_ALPHA_SIZE:
5054 case GL_RENDERBUFFER_DEPTH_SIZE:
5055 case GL_RENDERBUFFER_STENCIL_SIZE:
5056 break;
5057
5058 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5059 if (!context->getExtensions().framebufferMultisample)
5060 {
Jamie Madille0472f32018-11-27 16:32:45 -05005061 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005062 return false;
5063 }
5064 break;
5065
Geoff Lang79b91402018-10-04 15:11:30 -04005066 case GL_MEMORY_SIZE_ANGLE:
5067 if (!context->getExtensions().memorySize)
5068 {
Jamie Madille0472f32018-11-27 16:32:45 -05005069 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005070 return false;
5071 }
5072 break;
5073
Jamie Madillbe849e42017-05-02 15:49:00 -04005074 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005075 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005076 return false;
5077 }
5078
5079 if (length)
5080 {
5081 *length = 1;
5082 }
5083 return true;
5084}
5085
5086bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5087{
5088 if (length)
5089 {
5090 *length = 0;
5091 }
5092
5093 if (GetValidShader(context, shader) == nullptr)
5094 {
5095 return false;
5096 }
5097
5098 switch (pname)
5099 {
5100 case GL_SHADER_TYPE:
5101 case GL_DELETE_STATUS:
5102 case GL_COMPILE_STATUS:
5103 case GL_INFO_LOG_LENGTH:
5104 case GL_SHADER_SOURCE_LENGTH:
5105 break;
5106
5107 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5108 if (!context->getExtensions().translatedShaderSource)
5109 {
Jamie Madille0472f32018-11-27 16:32:45 -05005110 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005111 return false;
5112 }
5113 break;
5114
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005115 case GL_COMPLETION_STATUS_KHR:
5116 if (!context->getExtensions().parallelShaderCompile)
5117 {
Jamie Madille0472f32018-11-27 16:32:45 -05005118 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005119 return false;
5120 }
5121 break;
5122
Jamie Madillbe849e42017-05-02 15:49:00 -04005123 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005124 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005125 return false;
5126 }
5127
5128 if (length)
5129 {
5130 *length = 1;
5131 }
5132 return true;
5133}
5134
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005135bool ValidateGetTexParameterBase(Context *context,
5136 TextureType target,
5137 GLenum pname,
5138 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005139{
5140 if (length)
5141 {
5142 *length = 0;
5143 }
5144
5145 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5146 {
Jamie Madille0472f32018-11-27 16:32:45 -05005147 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005148 return false;
5149 }
5150
5151 if (context->getTargetTexture(target) == nullptr)
5152 {
5153 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005154 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005155 return false;
5156 }
5157
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005158 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5159 {
Jamie Madille0472f32018-11-27 16:32:45 -05005160 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005161 return false;
5162 }
5163
Jamie Madillbe849e42017-05-02 15:49:00 -04005164 switch (pname)
5165 {
5166 case GL_TEXTURE_MAG_FILTER:
5167 case GL_TEXTURE_MIN_FILTER:
5168 case GL_TEXTURE_WRAP_S:
5169 case GL_TEXTURE_WRAP_T:
5170 break;
5171
5172 case GL_TEXTURE_USAGE_ANGLE:
5173 if (!context->getExtensions().textureUsage)
5174 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005175 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005176 return false;
5177 }
5178 break;
5179
5180 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005181 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005182 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005183 return false;
5184 }
5185 break;
5186
5187 case GL_TEXTURE_IMMUTABLE_FORMAT:
5188 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005190 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005191 return false;
5192 }
5193 break;
5194
5195 case GL_TEXTURE_WRAP_R:
5196 case GL_TEXTURE_IMMUTABLE_LEVELS:
5197 case GL_TEXTURE_SWIZZLE_R:
5198 case GL_TEXTURE_SWIZZLE_G:
5199 case GL_TEXTURE_SWIZZLE_B:
5200 case GL_TEXTURE_SWIZZLE_A:
5201 case GL_TEXTURE_BASE_LEVEL:
5202 case GL_TEXTURE_MAX_LEVEL:
5203 case GL_TEXTURE_MIN_LOD:
5204 case GL_TEXTURE_MAX_LOD:
5205 case GL_TEXTURE_COMPARE_MODE:
5206 case GL_TEXTURE_COMPARE_FUNC:
5207 if (context->getClientMajorVersion() < 3)
5208 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005209 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Jamie Madillbe849e42017-05-02 15:49:00 -04005210 return false;
5211 }
5212 break;
5213
5214 case GL_TEXTURE_SRGB_DECODE_EXT:
5215 if (!context->getExtensions().textureSRGBDecode)
5216 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005217 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005218 return false;
5219 }
5220 break;
5221
Yunchao Hebacaa712018-01-30 14:01:39 +08005222 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5223 if (context->getClientVersion() < Version(3, 1))
5224 {
Jamie Madille0472f32018-11-27 16:32:45 -05005225 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005226 return false;
5227 }
5228 break;
5229
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005230 case GL_GENERATE_MIPMAP:
5231 case GL_TEXTURE_CROP_RECT_OES:
5232 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5233 // after GL_OES_draw_texture functionality implemented
5234 if (context->getClientMajorVersion() > 1)
5235 {
Jamie Madille0472f32018-11-27 16:32:45 -05005236 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005237 return false;
5238 }
5239 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005240
5241 case GL_MEMORY_SIZE_ANGLE:
5242 if (!context->getExtensions().memorySize)
5243 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005244 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang79b91402018-10-04 15:11:30 -04005245 return false;
5246 }
5247 break;
5248
Till Rathmannb8543632018-10-02 19:46:14 +02005249 case GL_TEXTURE_BORDER_COLOR:
5250 if (!context->getExtensions().textureBorderClamp)
5251 {
Jamie Madille0472f32018-11-27 16:32:45 -05005252 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005253 return false;
5254 }
5255 break;
5256
Jamie Madillbe849e42017-05-02 15:49:00 -04005257 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005258 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005259 return false;
5260 }
5261
5262 if (length)
5263 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005264 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005265 }
5266 return true;
5267}
5268
5269bool ValidateGetVertexAttribBase(Context *context,
5270 GLuint index,
5271 GLenum pname,
5272 GLsizei *length,
5273 bool pointer,
5274 bool pureIntegerEntryPoint)
5275{
5276 if (length)
5277 {
5278 *length = 0;
5279 }
5280
5281 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5282 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005283 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005284 return false;
5285 }
5286
5287 if (index >= context->getCaps().maxVertexAttributes)
5288 {
Jamie Madille0472f32018-11-27 16:32:45 -05005289 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005290 return false;
5291 }
5292
5293 if (pointer)
5294 {
5295 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5296 {
Jamie Madille0472f32018-11-27 16:32:45 -05005297 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005298 return false;
5299 }
5300 }
5301 else
5302 {
5303 switch (pname)
5304 {
5305 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5306 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5307 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5308 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5309 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5310 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5311 case GL_CURRENT_VERTEX_ATTRIB:
5312 break;
5313
5314 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5315 static_assert(
5316 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5317 "ANGLE extension enums not equal to GL enums.");
5318 if (context->getClientMajorVersion() < 3 &&
5319 !context->getExtensions().instancedArrays)
5320 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005321 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005322 return false;
5323 }
5324 break;
5325
5326 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5327 if (context->getClientMajorVersion() < 3)
5328 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005329 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005330 return false;
5331 }
5332 break;
5333
5334 case GL_VERTEX_ATTRIB_BINDING:
5335 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5336 if (context->getClientVersion() < ES_3_1)
5337 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005338 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005339 return false;
5340 }
5341 break;
5342
5343 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005344 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005345 return false;
5346 }
5347 }
5348
5349 if (length)
5350 {
5351 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5352 {
5353 *length = 4;
5354 }
5355 else
5356 {
5357 *length = 1;
5358 }
5359 }
5360
5361 return true;
5362}
5363
Jamie Madill4928b7c2017-06-20 12:57:39 -04005364bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005365 GLint x,
5366 GLint y,
5367 GLsizei width,
5368 GLsizei height,
5369 GLenum format,
5370 GLenum type,
5371 GLsizei bufSize,
5372 GLsizei *length,
5373 GLsizei *columns,
5374 GLsizei *rows,
5375 void *pixels)
5376{
5377 if (length != nullptr)
5378 {
5379 *length = 0;
5380 }
5381 if (rows != nullptr)
5382 {
5383 *rows = 0;
5384 }
5385 if (columns != nullptr)
5386 {
5387 *columns = 0;
5388 }
5389
5390 if (width < 0 || height < 0)
5391 {
Jamie Madille0472f32018-11-27 16:32:45 -05005392 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005393 return false;
5394 }
5395
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005396 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005397
Jamie Madill427064d2018-04-13 16:20:34 -04005398 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005399 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005400 return false;
5401 }
5402
Jamie Madille98b1b52018-03-08 09:47:23 -05005403 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005404 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005405 return false;
5406 }
5407
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005408 Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005409 ASSERT(framebuffer);
5410
5411 if (framebuffer->getReadBufferState() == GL_NONE)
5412 {
Jamie Madille0472f32018-11-27 16:32:45 -05005413 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005414 return false;
5415 }
5416
5417 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5418 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5419 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5420 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5421 // situation is an application error that would lead to a crash in ANGLE.
5422 if (readBuffer == nullptr)
5423 {
Jamie Madille0472f32018-11-27 16:32:45 -05005424 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005425 return false;
5426 }
5427
Martin Radev28031682017-07-28 14:47:56 +03005428 // ANGLE_multiview, Revision 1:
5429 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005430 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5431 // in the current read framebuffer is more than one.
5432 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005433 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005434 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
Martin Radev28031682017-07-28 14:47:56 +03005435 return false;
5436 }
5437
Geoff Lang280ba992017-04-18 16:30:58 -04005438 if (context->getExtensions().webglCompatibility)
5439 {
5440 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5441 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5442 // and type before validating the combination of format and type. However, the
5443 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5444 // verifies that GL_INVALID_OPERATION is generated.
5445 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5446 // dEQP/WebGL.
5447 if (!ValidReadPixelsFormatEnum(context, format))
5448 {
Jamie Madille0472f32018-11-27 16:32:45 -05005449 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005450 return false;
5451 }
5452
5453 if (!ValidReadPixelsTypeEnum(context, type))
5454 {
Jamie Madille0472f32018-11-27 16:32:45 -05005455 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005456 return false;
5457 }
5458 }
5459
Jamie Madill690c8eb2018-03-12 15:20:03 -04005460 GLenum currentFormat = GL_NONE;
5461 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5462
5463 GLenum currentType = GL_NONE;
5464 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5465
Jamie Madillbe849e42017-05-02 15:49:00 -04005466 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5467
5468 bool validFormatTypeCombination =
5469 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5470
5471 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5472 {
Jamie Madille0472f32018-11-27 16:32:45 -05005473 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005474 return false;
5475 }
5476
5477 // Check for pixel pack buffer related API errors
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005478 Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005479 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5480 {
5481 // ...the buffer object's data store is currently mapped.
Jamie Madillc3e37312018-11-30 15:25:39 -05005482 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madillbe849e42017-05-02 15:49:00 -04005483 return false;
5484 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005485 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5486 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5487 {
Jamie Madille0472f32018-11-27 16:32:45 -05005488 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005489 return false;
5490 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005491
5492 // .. the data would be packed to the buffer object such that the memory writes required
5493 // would exceed the data store size.
5494 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005495 const Extents size(width, height, 1);
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005496 const auto &pack = context->getState().getPackState();
Jamie Madillbe849e42017-05-02 15:49:00 -04005497
Jamie Madillca2ff382018-07-11 09:01:17 -04005498 GLuint endByte = 0;
5499 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005500 {
Jamie Madille0472f32018-11-27 16:32:45 -05005501 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005502 return false;
5503 }
5504
Jamie Madillbe849e42017-05-02 15:49:00 -04005505 if (bufSize >= 0)
5506 {
5507 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5508 {
Jamie Madille0472f32018-11-27 16:32:45 -05005509 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005510 return false;
5511 }
5512 }
5513
5514 if (pixelPackBuffer != nullptr)
5515 {
5516 CheckedNumeric<size_t> checkedEndByte(endByte);
5517 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5518 checkedEndByte += checkedOffset;
5519
5520 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5521 {
5522 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005523 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005524 return false;
5525 }
5526 }
5527
5528 if (pixelPackBuffer == nullptr && length != nullptr)
5529 {
5530 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5531 {
Jamie Madille0472f32018-11-27 16:32:45 -05005532 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005533 return false;
5534 }
5535
5536 *length = static_cast<GLsizei>(endByte);
5537 }
5538
Geoff Langa953b522018-02-21 16:56:23 -05005539 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005540 angle::CheckedNumeric<int> clippedExtent(length);
5541 if (start < 0)
5542 {
5543 // "subtract" the area that is less than 0
5544 clippedExtent += start;
5545 }
5546
Geoff Langa953b522018-02-21 16:56:23 -05005547 angle::CheckedNumeric<int> readExtent = start;
5548 readExtent += length;
5549 if (!readExtent.IsValid())
5550 {
5551 return false;
5552 }
5553
5554 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005555 {
5556 // Subtract the region to the right of the read buffer
5557 clippedExtent -= (readExtent - bufferSize);
5558 }
5559
5560 if (!clippedExtent.IsValid())
5561 {
Geoff Langa953b522018-02-21 16:56:23 -05005562 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005563 }
5564
Geoff Langa953b522018-02-21 16:56:23 -05005565 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5566 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005567 };
5568
Geoff Langa953b522018-02-21 16:56:23 -05005569 GLsizei writtenColumns = 0;
5570 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5571 {
Jamie Madille0472f32018-11-27 16:32:45 -05005572 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005573 return false;
5574 }
5575
5576 GLsizei writtenRows = 0;
5577 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5578 {
Jamie Madille0472f32018-11-27 16:32:45 -05005579 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005580 return false;
5581 }
5582
Jamie Madillbe849e42017-05-02 15:49:00 -04005583 if (columns != nullptr)
5584 {
Geoff Langa953b522018-02-21 16:56:23 -05005585 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005586 }
5587
5588 if (rows != nullptr)
5589 {
Geoff Langa953b522018-02-21 16:56:23 -05005590 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005591 }
5592
5593 return true;
5594}
5595
5596template <typename ParamType>
5597bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005598 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005599 GLenum pname,
5600 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005601 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005602 const ParamType *params)
5603{
5604 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5605 {
Jamie Madille0472f32018-11-27 16:32:45 -05005606 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005607 return false;
5608 }
5609
5610 if (context->getTargetTexture(target) == nullptr)
5611 {
5612 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005613 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005614 return false;
5615 }
5616
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005617 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005618 if (bufSize >= 0 && bufSize < minBufSize)
5619 {
Jamie Madille0472f32018-11-27 16:32:45 -05005620 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005621 return false;
5622 }
5623
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005624 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5625 {
Jamie Madille0472f32018-11-27 16:32:45 -05005626 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005627 return false;
5628 }
5629
Jamie Madillbe849e42017-05-02 15:49:00 -04005630 switch (pname)
5631 {
5632 case GL_TEXTURE_WRAP_R:
5633 case GL_TEXTURE_SWIZZLE_R:
5634 case GL_TEXTURE_SWIZZLE_G:
5635 case GL_TEXTURE_SWIZZLE_B:
5636 case GL_TEXTURE_SWIZZLE_A:
5637 case GL_TEXTURE_BASE_LEVEL:
5638 case GL_TEXTURE_MAX_LEVEL:
5639 case GL_TEXTURE_COMPARE_MODE:
5640 case GL_TEXTURE_COMPARE_FUNC:
5641 case GL_TEXTURE_MIN_LOD:
5642 case GL_TEXTURE_MAX_LOD:
5643 if (context->getClientMajorVersion() < 3)
5644 {
Jamie Madille0472f32018-11-27 16:32:45 -05005645 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005646 return false;
5647 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005648 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005649 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005650 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005651 return false;
5652 }
5653 break;
5654
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005655 case GL_GENERATE_MIPMAP:
5656 case GL_TEXTURE_CROP_RECT_OES:
5657 if (context->getClientMajorVersion() > 1)
5658 {
Jamie Madille0472f32018-11-27 16:32:45 -05005659 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005660 return false;
5661 }
5662 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005663 default:
5664 break;
5665 }
5666
Olli Etuahod310a432018-08-24 15:40:23 +03005667 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005668 {
5669 switch (pname)
5670 {
5671 case GL_TEXTURE_MIN_FILTER:
5672 case GL_TEXTURE_MAG_FILTER:
5673 case GL_TEXTURE_WRAP_S:
5674 case GL_TEXTURE_WRAP_T:
5675 case GL_TEXTURE_WRAP_R:
5676 case GL_TEXTURE_MIN_LOD:
5677 case GL_TEXTURE_MAX_LOD:
5678 case GL_TEXTURE_COMPARE_MODE:
5679 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005680 case GL_TEXTURE_BORDER_COLOR:
Jamie Madillc3e37312018-11-30 15:25:39 -05005681 context->validationError(GL_INVALID_ENUM, kInvalidPname);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005682 return false;
5683 }
5684 }
5685
Jamie Madillbe849e42017-05-02 15:49:00 -04005686 switch (pname)
5687 {
5688 case GL_TEXTURE_WRAP_S:
5689 case GL_TEXTURE_WRAP_T:
5690 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005691 {
5692 bool restrictedWrapModes =
5693 target == TextureType::External || target == TextureType::Rectangle;
5694 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04005695 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005696 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005697 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005698 }
5699 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005700
5701 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005702 {
5703 bool restrictedMinFilter =
5704 target == TextureType::External || target == TextureType::Rectangle;
5705 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04005706 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005707 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005708 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005709 }
5710 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005711
5712 case GL_TEXTURE_MAG_FILTER:
5713 if (!ValidateTextureMagFilterValue(context, params))
5714 {
5715 return false;
5716 }
5717 break;
5718
5719 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04005720 if (!context->getExtensions().textureUsage)
5721 {
Jamie Madille0472f32018-11-27 16:32:45 -05005722 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04005723 return false;
5724 }
5725
Jamie Madillbe849e42017-05-02 15:49:00 -04005726 switch (ConvertToGLenum(params[0]))
5727 {
5728 case GL_NONE:
5729 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
5730 break;
5731
5732 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005733 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005734 return false;
5735 }
5736 break;
5737
5738 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005739 {
5740 GLfloat paramValue = static_cast<GLfloat>(params[0]);
5741 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04005742 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005743 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005744 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005745 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
5746 }
5747 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005748
5749 case GL_TEXTURE_MIN_LOD:
5750 case GL_TEXTURE_MAX_LOD:
5751 // any value is permissible
5752 break;
5753
5754 case GL_TEXTURE_COMPARE_MODE:
5755 if (!ValidateTextureCompareModeValue(context, params))
5756 {
5757 return false;
5758 }
5759 break;
5760
5761 case GL_TEXTURE_COMPARE_FUNC:
5762 if (!ValidateTextureCompareFuncValue(context, params))
5763 {
5764 return false;
5765 }
5766 break;
5767
5768 case GL_TEXTURE_SWIZZLE_R:
5769 case GL_TEXTURE_SWIZZLE_G:
5770 case GL_TEXTURE_SWIZZLE_B:
5771 case GL_TEXTURE_SWIZZLE_A:
5772 switch (ConvertToGLenum(params[0]))
5773 {
5774 case GL_RED:
5775 case GL_GREEN:
5776 case GL_BLUE:
5777 case GL_ALPHA:
5778 case GL_ZERO:
5779 case GL_ONE:
5780 break;
5781
5782 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005783 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005784 return false;
5785 }
5786 break;
5787
5788 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005789 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005790 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005791 context->validationError(GL_INVALID_VALUE, kBaseLevelNegative);
Jamie Madillbe849e42017-05-02 15:49:00 -04005792 return false;
5793 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005794 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005795 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005796 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005797 return false;
5798 }
Olli Etuahod310a432018-08-24 15:40:23 +03005799 if ((target == TextureType::_2DMultisample ||
5800 target == TextureType::_2DMultisampleArray) &&
5801 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005802 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005803 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005804 return false;
5805 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005806 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005807 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005808 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005809 return false;
5810 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005811 break;
5812
5813 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005814 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005815 {
Jamie Madille0472f32018-11-27 16:32:45 -05005816 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005817 return false;
5818 }
5819 break;
5820
5821 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5822 if (context->getClientVersion() < Version(3, 1))
5823 {
Jamie Madille0472f32018-11-27 16:32:45 -05005824 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005825 return false;
5826 }
5827 switch (ConvertToGLenum(params[0]))
5828 {
5829 case GL_DEPTH_COMPONENT:
5830 case GL_STENCIL_INDEX:
5831 break;
5832
5833 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005834 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 return false;
5836 }
5837 break;
5838
5839 case GL_TEXTURE_SRGB_DECODE_EXT:
5840 if (!ValidateTextureSRGBDecodeValue(context, params))
5841 {
5842 return false;
5843 }
5844 break;
5845
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005846 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005847 if (context->getClientMajorVersion() > 1)
5848 {
Jamie Madille0472f32018-11-27 16:32:45 -05005849 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005850 return false;
5851 }
5852 break;
Till Rathmannb8543632018-10-02 19:46:14 +02005853
5854 case GL_TEXTURE_CROP_RECT_OES:
5855 if (context->getClientMajorVersion() > 1)
5856 {
Jamie Madille0472f32018-11-27 16:32:45 -05005857 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02005858 return false;
5859 }
5860 if (!vectorParams)
5861 {
Jamie Madille0472f32018-11-27 16:32:45 -05005862 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02005863 return false;
5864 }
5865 break;
5866
5867 case GL_TEXTURE_BORDER_COLOR:
5868 if (!context->getExtensions().textureBorderClamp)
5869 {
Jamie Madille0472f32018-11-27 16:32:45 -05005870 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005871 return false;
5872 }
5873 if (!vectorParams)
5874 {
Jamie Madille0472f32018-11-27 16:32:45 -05005875 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02005876 return false;
5877 }
5878 break;
5879
Jamie Madillbe849e42017-05-02 15:49:00 -04005880 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005881 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005882 return false;
5883 }
5884
5885 return true;
5886}
5887
Till Rathmannb8543632018-10-02 19:46:14 +02005888template bool ValidateTexParameterBase(Context *,
5889 TextureType,
5890 GLenum,
5891 GLsizei,
5892 bool,
5893 const GLfloat *);
5894template bool ValidateTexParameterBase(Context *,
5895 TextureType,
5896 GLenum,
5897 GLsizei,
5898 bool,
5899 const GLint *);
5900template bool ValidateTexParameterBase(Context *,
5901 TextureType,
5902 GLenum,
5903 GLsizei,
5904 bool,
5905 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04005906
Jamie Madill5b772312018-03-08 20:28:32 -05005907bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04005908{
5909 if (index >= MAX_VERTEX_ATTRIBS)
5910 {
Jamie Madille0472f32018-11-27 16:32:45 -05005911 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04005912 return false;
5913 }
5914
5915 return true;
5916}
5917
5918bool ValidateGetActiveUniformBlockivBase(Context *context,
5919 GLuint program,
5920 GLuint uniformBlockIndex,
5921 GLenum pname,
5922 GLsizei *length)
5923{
5924 if (length)
5925 {
5926 *length = 0;
5927 }
5928
5929 if (context->getClientMajorVersion() < 3)
5930 {
Jamie Madille0472f32018-11-27 16:32:45 -05005931 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04005932 return false;
5933 }
5934
5935 Program *programObject = GetValidProgram(context, program);
5936 if (!programObject)
5937 {
5938 return false;
5939 }
5940
5941 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
5942 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005943 context->validationError(GL_INVALID_VALUE, kIndexExceedsActiveUniformBlockCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04005944 return false;
5945 }
5946
5947 switch (pname)
5948 {
5949 case GL_UNIFORM_BLOCK_BINDING:
5950 case GL_UNIFORM_BLOCK_DATA_SIZE:
5951 case GL_UNIFORM_BLOCK_NAME_LENGTH:
5952 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
5953 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
5954 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
5955 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
5956 break;
5957
5958 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005959 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04005960 return false;
5961 }
5962
5963 if (length)
5964 {
5965 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
5966 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08005967 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04005968 programObject->getUniformBlockByIndex(uniformBlockIndex);
5969 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
5970 }
5971 else
5972 {
5973 *length = 1;
5974 }
5975 }
5976
5977 return true;
5978}
5979
Jamie Madill9696d072017-08-26 23:19:57 -04005980template <typename ParamType>
5981bool ValidateSamplerParameterBase(Context *context,
5982 GLuint sampler,
5983 GLenum pname,
5984 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005985 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04005986 ParamType *params)
5987{
5988 if (context->getClientMajorVersion() < 3)
5989 {
Jamie Madille0472f32018-11-27 16:32:45 -05005990 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04005991 return false;
5992 }
5993
5994 if (!context->isSampler(sampler))
5995 {
Jamie Madille0472f32018-11-27 16:32:45 -05005996 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04005997 return false;
5998 }
5999
Till Rathmannb8543632018-10-02 19:46:14 +02006000 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006001 if (bufSize >= 0 && bufSize < minBufSize)
6002 {
Jamie Madille0472f32018-11-27 16:32:45 -05006003 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006004 return false;
6005 }
6006
6007 switch (pname)
6008 {
6009 case GL_TEXTURE_WRAP_S:
6010 case GL_TEXTURE_WRAP_T:
6011 case GL_TEXTURE_WRAP_R:
6012 if (!ValidateTextureWrapModeValue(context, params, false))
6013 {
6014 return false;
6015 }
6016 break;
6017
6018 case GL_TEXTURE_MIN_FILTER:
6019 if (!ValidateTextureMinFilterValue(context, params, false))
6020 {
6021 return false;
6022 }
6023 break;
6024
6025 case GL_TEXTURE_MAG_FILTER:
6026 if (!ValidateTextureMagFilterValue(context, params))
6027 {
6028 return false;
6029 }
6030 break;
6031
6032 case GL_TEXTURE_MIN_LOD:
6033 case GL_TEXTURE_MAX_LOD:
6034 // any value is permissible
6035 break;
6036
6037 case GL_TEXTURE_COMPARE_MODE:
6038 if (!ValidateTextureCompareModeValue(context, params))
6039 {
6040 return false;
6041 }
6042 break;
6043
6044 case GL_TEXTURE_COMPARE_FUNC:
6045 if (!ValidateTextureCompareFuncValue(context, params))
6046 {
6047 return false;
6048 }
6049 break;
6050
6051 case GL_TEXTURE_SRGB_DECODE_EXT:
6052 if (!ValidateTextureSRGBDecodeValue(context, params))
6053 {
6054 return false;
6055 }
6056 break;
6057
Luc Ferron1b1a8642018-01-23 15:12:01 -05006058 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6059 {
6060 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6061 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6062 {
6063 return false;
6064 }
6065 }
6066 break;
6067
Till Rathmannb8543632018-10-02 19:46:14 +02006068 case GL_TEXTURE_BORDER_COLOR:
6069 if (!context->getExtensions().textureBorderClamp)
6070 {
Jamie Madille0472f32018-11-27 16:32:45 -05006071 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006072 return false;
6073 }
6074 if (!vectorParams)
6075 {
Jamie Madille0472f32018-11-27 16:32:45 -05006076 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006077 return false;
6078 }
6079 break;
6080
Jamie Madill9696d072017-08-26 23:19:57 -04006081 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006082 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006083 return false;
6084 }
6085
6086 return true;
6087}
6088
Till Rathmannb8543632018-10-02 19:46:14 +02006089template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6090template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6091template bool ValidateSamplerParameterBase(Context *,
6092 GLuint,
6093 GLenum,
6094 GLsizei,
6095 bool,
6096 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006097
6098bool ValidateGetSamplerParameterBase(Context *context,
6099 GLuint sampler,
6100 GLenum pname,
6101 GLsizei *length)
6102{
6103 if (length)
6104 {
6105 *length = 0;
6106 }
6107
6108 if (context->getClientMajorVersion() < 3)
6109 {
Jamie Madille0472f32018-11-27 16:32:45 -05006110 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006111 return false;
6112 }
6113
6114 if (!context->isSampler(sampler))
6115 {
Jamie Madille0472f32018-11-27 16:32:45 -05006116 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006117 return false;
6118 }
6119
6120 switch (pname)
6121 {
6122 case GL_TEXTURE_WRAP_S:
6123 case GL_TEXTURE_WRAP_T:
6124 case GL_TEXTURE_WRAP_R:
6125 case GL_TEXTURE_MIN_FILTER:
6126 case GL_TEXTURE_MAG_FILTER:
6127 case GL_TEXTURE_MIN_LOD:
6128 case GL_TEXTURE_MAX_LOD:
6129 case GL_TEXTURE_COMPARE_MODE:
6130 case GL_TEXTURE_COMPARE_FUNC:
6131 break;
6132
Luc Ferron1b1a8642018-01-23 15:12:01 -05006133 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6134 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6135 {
6136 return false;
6137 }
6138 break;
6139
Jamie Madill9696d072017-08-26 23:19:57 -04006140 case GL_TEXTURE_SRGB_DECODE_EXT:
6141 if (!context->getExtensions().textureSRGBDecode)
6142 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006143 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006144 return false;
6145 }
6146 break;
6147
Till Rathmannb8543632018-10-02 19:46:14 +02006148 case GL_TEXTURE_BORDER_COLOR:
6149 if (!context->getExtensions().textureBorderClamp)
6150 {
Jamie Madille0472f32018-11-27 16:32:45 -05006151 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006152 return false;
6153 }
6154 break;
6155
Jamie Madill9696d072017-08-26 23:19:57 -04006156 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006157 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006158 return false;
6159 }
6160
6161 if (length)
6162 {
Till Rathmannb8543632018-10-02 19:46:14 +02006163 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006164 }
6165 return true;
6166}
6167
6168bool ValidateGetInternalFormativBase(Context *context,
6169 GLenum target,
6170 GLenum internalformat,
6171 GLenum pname,
6172 GLsizei bufSize,
6173 GLsizei *numParams)
6174{
6175 if (numParams)
6176 {
6177 *numParams = 0;
6178 }
6179
6180 if (context->getClientMajorVersion() < 3)
6181 {
Jamie Madille0472f32018-11-27 16:32:45 -05006182 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006183 return false;
6184 }
6185
6186 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006187 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006188 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006189 context->validationError(GL_INVALID_ENUM, kFormatNotRenderable);
Jamie Madill9696d072017-08-26 23:19:57 -04006190 return false;
6191 }
6192
6193 switch (target)
6194 {
6195 case GL_RENDERBUFFER:
6196 break;
6197
6198 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006199 if (context->getClientVersion() < ES_3_1 &&
6200 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006201 {
Jamie Madill610640f2018-11-21 17:28:41 -05006202 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006203 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006204 return false;
6205 }
6206 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006207 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6208 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006209 {
Jamie Madille0472f32018-11-27 16:32:45 -05006210 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006211 return false;
6212 }
6213 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006214 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006215 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006216 return false;
6217 }
6218
6219 if (bufSize < 0)
6220 {
Jamie Madille0472f32018-11-27 16:32:45 -05006221 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006222 return false;
6223 }
6224
6225 GLsizei maxWriteParams = 0;
6226 switch (pname)
6227 {
6228 case GL_NUM_SAMPLE_COUNTS:
6229 maxWriteParams = 1;
6230 break;
6231
6232 case GL_SAMPLES:
6233 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6234 break;
6235
6236 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006237 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006238 return false;
6239 }
6240
6241 if (numParams)
6242 {
6243 // glGetInternalFormativ will not overflow bufSize
6244 *numParams = std::min(bufSize, maxWriteParams);
6245 }
6246
6247 return true;
6248}
6249
Jamie Madille98b1b52018-03-08 09:47:23 -05006250bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6251{
Jamie Madill427064d2018-04-13 16:20:34 -04006252 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006253 {
Jamie Madille0472f32018-11-27 16:32:45 -05006254 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006255 return false;
6256 }
6257 return true;
6258}
6259
Lingfeng Yang038dd532018-03-29 17:31:52 -07006260bool ValidateMultitextureUnit(Context *context, GLenum texture)
6261{
6262 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6263 {
Jamie Madille0472f32018-11-27 16:32:45 -05006264 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006265 return false;
6266 }
6267 return true;
6268}
6269
Olli Etuahod310a432018-08-24 15:40:23 +03006270bool ValidateTexStorageMultisample(Context *context,
6271 TextureType target,
6272 GLsizei samples,
6273 GLint internalFormat,
6274 GLsizei width,
6275 GLsizei height)
6276{
6277 const Caps &caps = context->getCaps();
6278 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6279 static_cast<GLuint>(height) > caps.max2DTextureSize)
6280 {
Jamie Madille0472f32018-11-27 16:32:45 -05006281 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006282 return false;
6283 }
6284
6285 if (samples == 0)
6286 {
Jamie Madille0472f32018-11-27 16:32:45 -05006287 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006288 return false;
6289 }
6290
6291 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6292 if (!formatCaps.textureAttachment)
6293 {
Jamie Madille0472f32018-11-27 16:32:45 -05006294 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006295 return false;
6296 }
6297
6298 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6299 // is one of the unsized base internalformats listed in table 8.11.
6300 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6301 if (formatInfo.internalFormat == GL_NONE)
6302 {
Jamie Madille0472f32018-11-27 16:32:45 -05006303 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006304 return false;
6305 }
6306
6307 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6308 {
Jamie Madille0472f32018-11-27 16:32:45 -05006309 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006310 return false;
6311 }
6312
6313 Texture *texture = context->getTargetTexture(target);
6314 if (!texture || texture->id() == 0)
6315 {
Jamie Madille0472f32018-11-27 16:32:45 -05006316 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006317 return false;
6318 }
6319
6320 if (texture->getImmutableFormat())
6321 {
Jamie Madille0472f32018-11-27 16:32:45 -05006322 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006323 return false;
6324 }
6325 return true;
6326}
6327
Yizhou Jiang7818a852018-09-06 15:02:04 +08006328bool ValidateTexStorage2DMultisampleBase(Context *context,
6329 TextureType target,
6330 GLsizei samples,
6331 GLint internalFormat,
6332 GLsizei width,
6333 GLsizei height)
6334{
6335 if (target != TextureType::_2DMultisample)
6336 {
Jamie Madille0472f32018-11-27 16:32:45 -05006337 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006338 return false;
6339 }
6340
6341 if (width < 1 || height < 1)
6342 {
Jamie Madille0472f32018-11-27 16:32:45 -05006343 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006344 return false;
6345 }
6346
6347 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6348}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006349
6350bool ValidateGetTexLevelParameterBase(Context *context,
6351 TextureTarget target,
6352 GLint level,
6353 GLenum pname,
6354 GLsizei *length)
6355{
6356
6357 if (length)
6358 {
6359 *length = 0;
6360 }
6361
6362 TextureType type = TextureTargetToType(target);
6363
6364 if (!ValidTexLevelDestinationTarget(context, type))
6365 {
Jamie Madille0472f32018-11-27 16:32:45 -05006366 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006367 return false;
6368 }
6369
6370 if (context->getTargetTexture(type) == nullptr)
6371 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006372 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006373 return false;
6374 }
6375
6376 if (!ValidMipLevel(context, type, level))
6377 {
Jamie Madille0472f32018-11-27 16:32:45 -05006378 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006379 return false;
6380 }
6381
6382 switch (pname)
6383 {
6384 case GL_TEXTURE_RED_TYPE:
6385 case GL_TEXTURE_GREEN_TYPE:
6386 case GL_TEXTURE_BLUE_TYPE:
6387 case GL_TEXTURE_ALPHA_TYPE:
6388 case GL_TEXTURE_DEPTH_TYPE:
6389 break;
6390 case GL_TEXTURE_RED_SIZE:
6391 case GL_TEXTURE_GREEN_SIZE:
6392 case GL_TEXTURE_BLUE_SIZE:
6393 case GL_TEXTURE_ALPHA_SIZE:
6394 case GL_TEXTURE_DEPTH_SIZE:
6395 case GL_TEXTURE_STENCIL_SIZE:
6396 case GL_TEXTURE_SHARED_SIZE:
6397 break;
6398 case GL_TEXTURE_INTERNAL_FORMAT:
6399 case GL_TEXTURE_WIDTH:
6400 case GL_TEXTURE_HEIGHT:
6401 case GL_TEXTURE_DEPTH:
6402 break;
6403 case GL_TEXTURE_SAMPLES:
6404 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6405 break;
6406 case GL_TEXTURE_COMPRESSED:
6407 break;
6408 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006409 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006410 return false;
6411 }
6412
6413 if (length)
6414 {
6415 *length = 1;
6416 }
6417 return true;
6418}
Yizhou Jiang7310da32018-11-05 14:40:01 +08006419
6420bool ValidateGetMultisamplefvBase(Context *context, GLenum pname, GLuint index, GLfloat *val)
6421{
6422 if (pname != GL_SAMPLE_POSITION)
6423 {
6424 context->validationError(GL_INVALID_ENUM, kInvalidPname);
6425 return false;
6426 }
6427
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006428 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
Yizhou Jiang7310da32018-11-05 14:40:01 +08006429 GLint samples = framebuffer->getSamples(context);
6430
6431 if (index >= static_cast<GLuint>(samples))
6432 {
6433 context->validationError(GL_INVALID_VALUE, kIndexExceedsSamples);
6434 return false;
6435 }
6436
6437 return true;
6438}
6439
6440bool ValidateSampleMaskiBase(Context *context, GLuint maskNumber, GLbitfield mask)
6441{
6442 if (maskNumber >= context->getCaps().maxSampleMaskWords)
6443 {
6444 context->validationError(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
6445 return false;
6446 }
6447
6448 return true;
6449}
Jamie Madill9fa54ea2019-01-02 18:38:33 -05006450
6451void RecordDrawAttribsError(Context *context)
6452{
6453 // An overflow can happen when adding the offset. Check against a special constant.
6454 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
6455 VertexAttribute::kIntegerOverflow ||
6456 context->getStateCache().getInstancedVertexElementLimit() ==
6457 VertexAttribute::kIntegerOverflow)
6458 {
6459 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
6460 }
6461 else
6462 {
6463 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
6464 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
6465 context->validationError(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
6466 }
6467}
Jamie Madillc29968b2016-01-20 11:17:23 -05006468} // namespace gl