blob: b427aba11673dc2a4a07092222a13c75b95b83b2 [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 Madill6e18a232019-01-16 13:27:14 -0500370 return ValidateComponentTypeMasks(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
Jamie Madill6e18a232019-01-16 13:27:14 -0500386 vaoAttribEnabledMask |= vaoAttribEnabledMask << kMaxComponentTypeMaskIndex;
Brandon Jonesc405ae72017-12-06 14:15:03 -0800387 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
388 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
389
Jamie Madill6e18a232019-01-16 13:27:14 -0500390 return ValidateComponentTypeMasks(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,
Jamie Madilldd34b3b2019-01-16 09:59:54 -0500985 VertexAttribType type,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400986 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,
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004806 VertexAttribType type,
Shao80957d92017-02-20 21:25:59 +08004807 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
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004822 // This validation could be improved using a table and better encapsulation.
Shao80957d92017-02-20 21:25:59 +08004823 switch (type)
4824 {
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004825 case VertexAttribType::Byte:
4826 case VertexAttribType::UnsignedByte:
4827 case VertexAttribType::Short:
4828 case VertexAttribType::UnsignedShort:
Shao80957d92017-02-20 21:25:59 +08004829 break;
4830
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004831 case VertexAttribType::Int:
4832 case VertexAttribType::UnsignedInt:
Shao80957d92017-02-20 21:25:59 +08004833 if (context->getClientMajorVersion() < 3)
4834 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004835 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004836 return false;
4837 }
4838 break;
4839
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004840 case VertexAttribType::Fixed:
4841 case VertexAttribType::Float:
Shao80957d92017-02-20 21:25:59 +08004842 if (pureInteger)
4843 {
Jamie Madille0472f32018-11-27 16:32:45 -05004844 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004845 return false;
4846 }
4847 break;
4848
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004849 case VertexAttribType::HalfFloat:
Shao80957d92017-02-20 21:25:59 +08004850 if (context->getClientMajorVersion() < 3)
4851 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004852 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004853 return false;
4854 }
4855 if (pureInteger)
4856 {
Jamie Madille0472f32018-11-27 16:32:45 -05004857 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004858 return false;
4859 }
4860 break;
4861
Jamie Madilldd34b3b2019-01-16 09:59:54 -05004862 case VertexAttribType::Int2101010:
4863 case VertexAttribType::UnsignedInt2101010:
Shao80957d92017-02-20 21:25:59 +08004864 if (context->getClientMajorVersion() < 3)
4865 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004866 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Shao80957d92017-02-20 21:25:59 +08004867 return false;
4868 }
4869 if (pureInteger)
4870 {
Jamie Madille0472f32018-11-27 16:32:45 -05004871 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08004872 return false;
4873 }
4874 if (size != 4)
4875 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004876 context->validationError(GL_INVALID_OPERATION, kInvalidVertexAttribSize2101010);
Shao80957d92017-02-20 21:25:59 +08004877 return false;
4878 }
4879 break;
4880
4881 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004882 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08004883 return false;
4884 }
4885
4886 return true;
4887}
4888
Geoff Lang76e65652017-03-27 14:58:02 -04004889// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
4890// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
4891// specified clear value and the type of a buffer that is being cleared generates an
4892// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05004893bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04004894 GLint drawbuffer,
4895 const GLenum *validComponentTypes,
4896 size_t validComponentTypeCount)
4897{
4898 const FramebufferAttachment *attachment =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004899 context->getState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
Geoff Lang76e65652017-03-27 14:58:02 -04004900 if (attachment)
4901 {
4902 GLenum componentType = attachment->getFormat().info->componentType;
4903 const GLenum *end = validComponentTypes + validComponentTypeCount;
4904 if (std::find(validComponentTypes, end, componentType) == end)
4905 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004906 context->validationError(GL_INVALID_OPERATION, kNoDefinedClearConversion);
Geoff Lang76e65652017-03-27 14:58:02 -04004907 return false;
4908 }
4909 }
4910
4911 return true;
4912}
4913
Jamie Madill5b772312018-03-08 20:28:32 -05004914bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04004915{
4916 if (!ValidateRobustEntryPoint(context, dataSize))
4917 {
4918 return false;
4919 }
4920
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004921 Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04004922 if (pixelUnpackBuffer == nullptr)
4923 {
4924 if (dataSize < imageSize)
4925 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004926 context->validationError(GL_INVALID_OPERATION, kCompressedDataSizeTooSmall);
Corentin Wallezb2931602017-04-11 15:58:57 -04004927 }
4928 }
4929 return true;
4930}
4931
Jamie Madill5b772312018-03-08 20:28:32 -05004932bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004933 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04004934 GLenum pname,
4935 bool pointerVersion,
4936 GLsizei *numParams)
4937{
4938 if (numParams)
4939 {
4940 *numParams = 0;
4941 }
4942
Corentin Walleze4477002017-12-01 14:39:58 -05004943 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04004944 {
Jamie Madille0472f32018-11-27 16:32:45 -05004945 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04004946 return false;
4947 }
4948
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004949 const Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04004950 if (!buffer)
4951 {
4952 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05004953 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04004954 return false;
4955 }
4956
4957 const Extensions &extensions = context->getExtensions();
4958
4959 switch (pname)
4960 {
4961 case GL_BUFFER_USAGE:
4962 case GL_BUFFER_SIZE:
4963 break;
4964
4965 case GL_BUFFER_ACCESS_OES:
4966 if (!extensions.mapBuffer)
4967 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004968 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004969 return false;
4970 }
4971 break;
4972
4973 case GL_BUFFER_MAPPED:
4974 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
4975 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
4976 !extensions.mapBufferRange)
4977 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004978 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004979 return false;
4980 }
4981 break;
4982
4983 case GL_BUFFER_MAP_POINTER:
4984 if (!pointerVersion)
4985 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004986 context->validationError(GL_INVALID_ENUM, kInvalidMapPointerQuery);
Jamie Madillbe849e42017-05-02 15:49:00 -04004987 return false;
4988 }
4989 break;
4990
4991 case GL_BUFFER_ACCESS_FLAGS:
4992 case GL_BUFFER_MAP_OFFSET:
4993 case GL_BUFFER_MAP_LENGTH:
4994 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
4995 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004996 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04004997 return false;
4998 }
4999 break;
5000
Geoff Lang79b91402018-10-04 15:11:30 -04005001 case GL_MEMORY_SIZE_ANGLE:
5002 if (!context->getExtensions().memorySize)
5003 {
Jamie Madille0472f32018-11-27 16:32:45 -05005004 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005005 return false;
5006 }
5007 break;
5008
Jamie Madillbe849e42017-05-02 15:49:00 -04005009 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005010 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005011 return false;
5012 }
5013
5014 // All buffer parameter queries return one value.
5015 if (numParams)
5016 {
5017 *numParams = 1;
5018 }
5019
5020 return true;
5021}
5022
5023bool ValidateGetRenderbufferParameterivBase(Context *context,
5024 GLenum target,
5025 GLenum pname,
5026 GLsizei *length)
5027{
5028 if (length)
5029 {
5030 *length = 0;
5031 }
5032
5033 if (target != GL_RENDERBUFFER)
5034 {
Jamie Madille0472f32018-11-27 16:32:45 -05005035 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005036 return false;
5037 }
5038
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005039 Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005040 if (renderbuffer == nullptr)
5041 {
Jamie Madille0472f32018-11-27 16:32:45 -05005042 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005043 return false;
5044 }
5045
5046 switch (pname)
5047 {
5048 case GL_RENDERBUFFER_WIDTH:
5049 case GL_RENDERBUFFER_HEIGHT:
5050 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5051 case GL_RENDERBUFFER_RED_SIZE:
5052 case GL_RENDERBUFFER_GREEN_SIZE:
5053 case GL_RENDERBUFFER_BLUE_SIZE:
5054 case GL_RENDERBUFFER_ALPHA_SIZE:
5055 case GL_RENDERBUFFER_DEPTH_SIZE:
5056 case GL_RENDERBUFFER_STENCIL_SIZE:
5057 break;
5058
5059 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5060 if (!context->getExtensions().framebufferMultisample)
5061 {
Jamie Madille0472f32018-11-27 16:32:45 -05005062 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005063 return false;
5064 }
5065 break;
5066
Geoff Lang79b91402018-10-04 15:11:30 -04005067 case GL_MEMORY_SIZE_ANGLE:
5068 if (!context->getExtensions().memorySize)
5069 {
Jamie Madille0472f32018-11-27 16:32:45 -05005070 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005071 return false;
5072 }
5073 break;
5074
Jamie Madillbe849e42017-05-02 15:49:00 -04005075 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005076 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005077 return false;
5078 }
5079
5080 if (length)
5081 {
5082 *length = 1;
5083 }
5084 return true;
5085}
5086
5087bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5088{
5089 if (length)
5090 {
5091 *length = 0;
5092 }
5093
5094 if (GetValidShader(context, shader) == nullptr)
5095 {
5096 return false;
5097 }
5098
5099 switch (pname)
5100 {
5101 case GL_SHADER_TYPE:
5102 case GL_DELETE_STATUS:
5103 case GL_COMPILE_STATUS:
5104 case GL_INFO_LOG_LENGTH:
5105 case GL_SHADER_SOURCE_LENGTH:
5106 break;
5107
5108 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5109 if (!context->getExtensions().translatedShaderSource)
5110 {
Jamie Madille0472f32018-11-27 16:32:45 -05005111 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005112 return false;
5113 }
5114 break;
5115
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005116 case GL_COMPLETION_STATUS_KHR:
5117 if (!context->getExtensions().parallelShaderCompile)
5118 {
Jamie Madille0472f32018-11-27 16:32:45 -05005119 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005120 return false;
5121 }
5122 break;
5123
Jamie Madillbe849e42017-05-02 15:49:00 -04005124 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005125 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005126 return false;
5127 }
5128
5129 if (length)
5130 {
5131 *length = 1;
5132 }
5133 return true;
5134}
5135
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005136bool ValidateGetTexParameterBase(Context *context,
5137 TextureType target,
5138 GLenum pname,
5139 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005140{
5141 if (length)
5142 {
5143 *length = 0;
5144 }
5145
5146 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5147 {
Jamie Madille0472f32018-11-27 16:32:45 -05005148 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005149 return false;
5150 }
5151
5152 if (context->getTargetTexture(target) == nullptr)
5153 {
5154 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005155 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005156 return false;
5157 }
5158
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005159 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5160 {
Jamie Madille0472f32018-11-27 16:32:45 -05005161 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005162 return false;
5163 }
5164
Jamie Madillbe849e42017-05-02 15:49:00 -04005165 switch (pname)
5166 {
5167 case GL_TEXTURE_MAG_FILTER:
5168 case GL_TEXTURE_MIN_FILTER:
5169 case GL_TEXTURE_WRAP_S:
5170 case GL_TEXTURE_WRAP_T:
5171 break;
5172
5173 case GL_TEXTURE_USAGE_ANGLE:
5174 if (!context->getExtensions().textureUsage)
5175 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005176 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005177 return false;
5178 }
5179 break;
5180
5181 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005182 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005183 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005184 return false;
5185 }
5186 break;
5187
5188 case GL_TEXTURE_IMMUTABLE_FORMAT:
5189 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5190 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005191 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005192 return false;
5193 }
5194 break;
5195
5196 case GL_TEXTURE_WRAP_R:
5197 case GL_TEXTURE_IMMUTABLE_LEVELS:
5198 case GL_TEXTURE_SWIZZLE_R:
5199 case GL_TEXTURE_SWIZZLE_G:
5200 case GL_TEXTURE_SWIZZLE_B:
5201 case GL_TEXTURE_SWIZZLE_A:
5202 case GL_TEXTURE_BASE_LEVEL:
5203 case GL_TEXTURE_MAX_LEVEL:
5204 case GL_TEXTURE_MIN_LOD:
5205 case GL_TEXTURE_MAX_LOD:
5206 case GL_TEXTURE_COMPARE_MODE:
5207 case GL_TEXTURE_COMPARE_FUNC:
5208 if (context->getClientMajorVersion() < 3)
5209 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005210 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES30);
Jamie Madillbe849e42017-05-02 15:49:00 -04005211 return false;
5212 }
5213 break;
5214
5215 case GL_TEXTURE_SRGB_DECODE_EXT:
5216 if (!context->getExtensions().textureSRGBDecode)
5217 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005218 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005219 return false;
5220 }
5221 break;
5222
Yunchao Hebacaa712018-01-30 14:01:39 +08005223 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5224 if (context->getClientVersion() < Version(3, 1))
5225 {
Jamie Madille0472f32018-11-27 16:32:45 -05005226 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005227 return false;
5228 }
5229 break;
5230
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005231 case GL_GENERATE_MIPMAP:
5232 case GL_TEXTURE_CROP_RECT_OES:
5233 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5234 // after GL_OES_draw_texture functionality implemented
5235 if (context->getClientMajorVersion() > 1)
5236 {
Jamie Madille0472f32018-11-27 16:32:45 -05005237 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005238 return false;
5239 }
5240 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005241
5242 case GL_MEMORY_SIZE_ANGLE:
5243 if (!context->getExtensions().memorySize)
5244 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005245 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang79b91402018-10-04 15:11:30 -04005246 return false;
5247 }
5248 break;
5249
Till Rathmannb8543632018-10-02 19:46:14 +02005250 case GL_TEXTURE_BORDER_COLOR:
5251 if (!context->getExtensions().textureBorderClamp)
5252 {
Jamie Madille0472f32018-11-27 16:32:45 -05005253 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005254 return false;
5255 }
5256 break;
5257
Jamie Madillbe849e42017-05-02 15:49:00 -04005258 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005259 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005260 return false;
5261 }
5262
5263 if (length)
5264 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005265 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005266 }
5267 return true;
5268}
5269
5270bool ValidateGetVertexAttribBase(Context *context,
5271 GLuint index,
5272 GLenum pname,
5273 GLsizei *length,
5274 bool pointer,
5275 bool pureIntegerEntryPoint)
5276{
5277 if (length)
5278 {
5279 *length = 0;
5280 }
5281
5282 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5283 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005284 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005285 return false;
5286 }
5287
5288 if (index >= context->getCaps().maxVertexAttributes)
5289 {
Jamie Madille0472f32018-11-27 16:32:45 -05005290 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005291 return false;
5292 }
5293
5294 if (pointer)
5295 {
5296 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5297 {
Jamie Madille0472f32018-11-27 16:32:45 -05005298 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005299 return false;
5300 }
5301 }
5302 else
5303 {
5304 switch (pname)
5305 {
5306 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5307 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5308 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5309 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5310 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5311 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5312 case GL_CURRENT_VERTEX_ATTRIB:
5313 break;
5314
5315 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5316 static_assert(
5317 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5318 "ANGLE extension enums not equal to GL enums.");
5319 if (context->getClientMajorVersion() < 3 &&
5320 !context->getExtensions().instancedArrays)
5321 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005322 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005323 return false;
5324 }
5325 break;
5326
5327 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5328 if (context->getClientMajorVersion() < 3)
5329 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005330 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005331 return false;
5332 }
5333 break;
5334
5335 case GL_VERTEX_ATTRIB_BINDING:
5336 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5337 if (context->getClientVersion() < ES_3_1)
5338 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005339 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005340 return false;
5341 }
5342 break;
5343
5344 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005345 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005346 return false;
5347 }
5348 }
5349
5350 if (length)
5351 {
5352 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5353 {
5354 *length = 4;
5355 }
5356 else
5357 {
5358 *length = 1;
5359 }
5360 }
5361
5362 return true;
5363}
5364
Jamie Madill4928b7c2017-06-20 12:57:39 -04005365bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005366 GLint x,
5367 GLint y,
5368 GLsizei width,
5369 GLsizei height,
5370 GLenum format,
5371 GLenum type,
5372 GLsizei bufSize,
5373 GLsizei *length,
5374 GLsizei *columns,
5375 GLsizei *rows,
5376 void *pixels)
5377{
5378 if (length != nullptr)
5379 {
5380 *length = 0;
5381 }
5382 if (rows != nullptr)
5383 {
5384 *rows = 0;
5385 }
5386 if (columns != nullptr)
5387 {
5388 *columns = 0;
5389 }
5390
5391 if (width < 0 || height < 0)
5392 {
Jamie Madille0472f32018-11-27 16:32:45 -05005393 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005394 return false;
5395 }
5396
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005397 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005398
Jamie Madill427064d2018-04-13 16:20:34 -04005399 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005400 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005401 return false;
5402 }
5403
Jamie Madille98b1b52018-03-08 09:47:23 -05005404 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005405 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005406 return false;
5407 }
5408
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005409 Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005410 ASSERT(framebuffer);
5411
5412 if (framebuffer->getReadBufferState() == GL_NONE)
5413 {
Jamie Madille0472f32018-11-27 16:32:45 -05005414 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005415 return false;
5416 }
5417
5418 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5419 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5420 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5421 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5422 // situation is an application error that would lead to a crash in ANGLE.
5423 if (readBuffer == nullptr)
5424 {
Jamie Madille0472f32018-11-27 16:32:45 -05005425 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005426 return false;
5427 }
5428
Martin Radev28031682017-07-28 14:47:56 +03005429 // ANGLE_multiview, Revision 1:
5430 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005431 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5432 // in the current read framebuffer is more than one.
5433 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005434 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005435 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kMultiviewReadFramebuffer);
Martin Radev28031682017-07-28 14:47:56 +03005436 return false;
5437 }
5438
Geoff Lang280ba992017-04-18 16:30:58 -04005439 if (context->getExtensions().webglCompatibility)
5440 {
5441 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5442 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5443 // and type before validating the combination of format and type. However, the
5444 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5445 // verifies that GL_INVALID_OPERATION is generated.
5446 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5447 // dEQP/WebGL.
5448 if (!ValidReadPixelsFormatEnum(context, format))
5449 {
Jamie Madille0472f32018-11-27 16:32:45 -05005450 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005451 return false;
5452 }
5453
5454 if (!ValidReadPixelsTypeEnum(context, type))
5455 {
Jamie Madille0472f32018-11-27 16:32:45 -05005456 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005457 return false;
5458 }
5459 }
5460
Jamie Madill690c8eb2018-03-12 15:20:03 -04005461 GLenum currentFormat = GL_NONE;
5462 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5463
5464 GLenum currentType = GL_NONE;
5465 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5466
Jamie Madillbe849e42017-05-02 15:49:00 -04005467 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5468
5469 bool validFormatTypeCombination =
5470 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5471
5472 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5473 {
Jamie Madille0472f32018-11-27 16:32:45 -05005474 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005475 return false;
5476 }
5477
5478 // Check for pixel pack buffer related API errors
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005479 Buffer *pixelPackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005480 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5481 {
5482 // ...the buffer object's data store is currently mapped.
Jamie Madillc3e37312018-11-30 15:25:39 -05005483 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madillbe849e42017-05-02 15:49:00 -04005484 return false;
5485 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005486 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5487 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5488 {
Jamie Madille0472f32018-11-27 16:32:45 -05005489 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005490 return false;
5491 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005492
5493 // .. the data would be packed to the buffer object such that the memory writes required
5494 // would exceed the data store size.
5495 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005496 const Extents size(width, height, 1);
Jamie Madillc3dc5d42018-12-30 12:12:04 -05005497 const auto &pack = context->getState().getPackState();
Jamie Madillbe849e42017-05-02 15:49:00 -04005498
Jamie Madillca2ff382018-07-11 09:01:17 -04005499 GLuint endByte = 0;
5500 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005501 {
Jamie Madille0472f32018-11-27 16:32:45 -05005502 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005503 return false;
5504 }
5505
Jamie Madillbe849e42017-05-02 15:49:00 -04005506 if (bufSize >= 0)
5507 {
5508 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5509 {
Jamie Madille0472f32018-11-27 16:32:45 -05005510 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005511 return false;
5512 }
5513 }
5514
5515 if (pixelPackBuffer != nullptr)
5516 {
5517 CheckedNumeric<size_t> checkedEndByte(endByte);
5518 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5519 checkedEndByte += checkedOffset;
5520
5521 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5522 {
5523 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005524 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005525 return false;
5526 }
5527 }
5528
5529 if (pixelPackBuffer == nullptr && length != nullptr)
5530 {
5531 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5532 {
Jamie Madille0472f32018-11-27 16:32:45 -05005533 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005534 return false;
5535 }
5536
5537 *length = static_cast<GLsizei>(endByte);
5538 }
5539
Geoff Langa953b522018-02-21 16:56:23 -05005540 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005541 angle::CheckedNumeric<int> clippedExtent(length);
5542 if (start < 0)
5543 {
5544 // "subtract" the area that is less than 0
5545 clippedExtent += start;
5546 }
5547
Geoff Langa953b522018-02-21 16:56:23 -05005548 angle::CheckedNumeric<int> readExtent = start;
5549 readExtent += length;
5550 if (!readExtent.IsValid())
5551 {
5552 return false;
5553 }
5554
5555 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005556 {
5557 // Subtract the region to the right of the read buffer
5558 clippedExtent -= (readExtent - bufferSize);
5559 }
5560
5561 if (!clippedExtent.IsValid())
5562 {
Geoff Langa953b522018-02-21 16:56:23 -05005563 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005564 }
5565
Geoff Langa953b522018-02-21 16:56:23 -05005566 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5567 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005568 };
5569
Geoff Langa953b522018-02-21 16:56:23 -05005570 GLsizei writtenColumns = 0;
5571 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5572 {
Jamie Madille0472f32018-11-27 16:32:45 -05005573 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005574 return false;
5575 }
5576
5577 GLsizei writtenRows = 0;
5578 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5579 {
Jamie Madille0472f32018-11-27 16:32:45 -05005580 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005581 return false;
5582 }
5583
Jamie Madillbe849e42017-05-02 15:49:00 -04005584 if (columns != nullptr)
5585 {
Geoff Langa953b522018-02-21 16:56:23 -05005586 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005587 }
5588
5589 if (rows != nullptr)
5590 {
Geoff Langa953b522018-02-21 16:56:23 -05005591 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005592 }
5593
5594 return true;
5595}
5596
5597template <typename ParamType>
5598bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005599 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005600 GLenum pname,
5601 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005602 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005603 const ParamType *params)
5604{
5605 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5606 {
Jamie Madille0472f32018-11-27 16:32:45 -05005607 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005608 return false;
5609 }
5610
5611 if (context->getTargetTexture(target) == nullptr)
5612 {
5613 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005614 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005615 return false;
5616 }
5617
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005618 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005619 if (bufSize >= 0 && bufSize < minBufSize)
5620 {
Jamie Madille0472f32018-11-27 16:32:45 -05005621 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005622 return false;
5623 }
5624
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005625 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5626 {
Jamie Madille0472f32018-11-27 16:32:45 -05005627 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005628 return false;
5629 }
5630
Jamie Madillbe849e42017-05-02 15:49:00 -04005631 switch (pname)
5632 {
5633 case GL_TEXTURE_WRAP_R:
5634 case GL_TEXTURE_SWIZZLE_R:
5635 case GL_TEXTURE_SWIZZLE_G:
5636 case GL_TEXTURE_SWIZZLE_B:
5637 case GL_TEXTURE_SWIZZLE_A:
5638 case GL_TEXTURE_BASE_LEVEL:
5639 case GL_TEXTURE_MAX_LEVEL:
5640 case GL_TEXTURE_COMPARE_MODE:
5641 case GL_TEXTURE_COMPARE_FUNC:
5642 case GL_TEXTURE_MIN_LOD:
5643 case GL_TEXTURE_MAX_LOD:
5644 if (context->getClientMajorVersion() < 3)
5645 {
Jamie Madille0472f32018-11-27 16:32:45 -05005646 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005647 return false;
5648 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005649 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005650 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005651 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005652 return false;
5653 }
5654 break;
5655
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005656 case GL_GENERATE_MIPMAP:
5657 case GL_TEXTURE_CROP_RECT_OES:
5658 if (context->getClientMajorVersion() > 1)
5659 {
Jamie Madille0472f32018-11-27 16:32:45 -05005660 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005661 return false;
5662 }
5663 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005664 default:
5665 break;
5666 }
5667
Olli Etuahod310a432018-08-24 15:40:23 +03005668 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005669 {
5670 switch (pname)
5671 {
5672 case GL_TEXTURE_MIN_FILTER:
5673 case GL_TEXTURE_MAG_FILTER:
5674 case GL_TEXTURE_WRAP_S:
5675 case GL_TEXTURE_WRAP_T:
5676 case GL_TEXTURE_WRAP_R:
5677 case GL_TEXTURE_MIN_LOD:
5678 case GL_TEXTURE_MAX_LOD:
5679 case GL_TEXTURE_COMPARE_MODE:
5680 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005681 case GL_TEXTURE_BORDER_COLOR:
Jamie Madillc3e37312018-11-30 15:25:39 -05005682 context->validationError(GL_INVALID_ENUM, kInvalidPname);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005683 return false;
5684 }
5685 }
5686
Jamie Madillbe849e42017-05-02 15:49:00 -04005687 switch (pname)
5688 {
5689 case GL_TEXTURE_WRAP_S:
5690 case GL_TEXTURE_WRAP_T:
5691 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005692 {
5693 bool restrictedWrapModes =
5694 target == TextureType::External || target == TextureType::Rectangle;
5695 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04005696 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005697 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005698 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005699 }
5700 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005701
5702 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005703 {
5704 bool restrictedMinFilter =
5705 target == TextureType::External || target == TextureType::Rectangle;
5706 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04005707 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005708 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005709 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005710 }
5711 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005712
5713 case GL_TEXTURE_MAG_FILTER:
5714 if (!ValidateTextureMagFilterValue(context, params))
5715 {
5716 return false;
5717 }
5718 break;
5719
5720 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04005721 if (!context->getExtensions().textureUsage)
5722 {
Jamie Madille0472f32018-11-27 16:32:45 -05005723 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04005724 return false;
5725 }
5726
Jamie Madillbe849e42017-05-02 15:49:00 -04005727 switch (ConvertToGLenum(params[0]))
5728 {
5729 case GL_NONE:
5730 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
5731 break;
5732
5733 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005734 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005735 return false;
5736 }
5737 break;
5738
5739 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005740 {
5741 GLfloat paramValue = static_cast<GLfloat>(params[0]);
5742 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04005743 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005744 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005745 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005746 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
5747 }
5748 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005749
5750 case GL_TEXTURE_MIN_LOD:
5751 case GL_TEXTURE_MAX_LOD:
5752 // any value is permissible
5753 break;
5754
5755 case GL_TEXTURE_COMPARE_MODE:
5756 if (!ValidateTextureCompareModeValue(context, params))
5757 {
5758 return false;
5759 }
5760 break;
5761
5762 case GL_TEXTURE_COMPARE_FUNC:
5763 if (!ValidateTextureCompareFuncValue(context, params))
5764 {
5765 return false;
5766 }
5767 break;
5768
5769 case GL_TEXTURE_SWIZZLE_R:
5770 case GL_TEXTURE_SWIZZLE_G:
5771 case GL_TEXTURE_SWIZZLE_B:
5772 case GL_TEXTURE_SWIZZLE_A:
5773 switch (ConvertToGLenum(params[0]))
5774 {
5775 case GL_RED:
5776 case GL_GREEN:
5777 case GL_BLUE:
5778 case GL_ALPHA:
5779 case GL_ZERO:
5780 case GL_ONE:
5781 break;
5782
5783 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005784 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005785 return false;
5786 }
5787 break;
5788
5789 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005790 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005791 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005792 context->validationError(GL_INVALID_VALUE, kBaseLevelNegative);
Jamie Madillbe849e42017-05-02 15:49:00 -04005793 return false;
5794 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005795 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005796 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005797 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005798 return false;
5799 }
Olli Etuahod310a432018-08-24 15:40:23 +03005800 if ((target == TextureType::_2DMultisample ||
5801 target == TextureType::_2DMultisampleArray) &&
5802 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005803 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005804 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
JiangYizhou4cff8d62017-07-06 14:54:09 +08005805 return false;
5806 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005807 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005808 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005809 context->validationError(GL_INVALID_OPERATION, kBaseLevelNonZero);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005810 return false;
5811 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005812 break;
5813
5814 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05005815 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04005816 {
Jamie Madille0472f32018-11-27 16:32:45 -05005817 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005818 return false;
5819 }
5820 break;
5821
5822 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5823 if (context->getClientVersion() < Version(3, 1))
5824 {
Jamie Madille0472f32018-11-27 16:32:45 -05005825 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04005826 return false;
5827 }
5828 switch (ConvertToGLenum(params[0]))
5829 {
5830 case GL_DEPTH_COMPONENT:
5831 case GL_STENCIL_INDEX:
5832 break;
5833
5834 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005835 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005836 return false;
5837 }
5838 break;
5839
5840 case GL_TEXTURE_SRGB_DECODE_EXT:
5841 if (!ValidateTextureSRGBDecodeValue(context, params))
5842 {
5843 return false;
5844 }
5845 break;
5846
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005847 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005848 if (context->getClientMajorVersion() > 1)
5849 {
Jamie Madille0472f32018-11-27 16:32:45 -05005850 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005851 return false;
5852 }
5853 break;
Till Rathmannb8543632018-10-02 19:46:14 +02005854
5855 case GL_TEXTURE_CROP_RECT_OES:
5856 if (context->getClientMajorVersion() > 1)
5857 {
Jamie Madille0472f32018-11-27 16:32:45 -05005858 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02005859 return false;
5860 }
5861 if (!vectorParams)
5862 {
Jamie Madille0472f32018-11-27 16:32:45 -05005863 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02005864 return false;
5865 }
5866 break;
5867
5868 case GL_TEXTURE_BORDER_COLOR:
5869 if (!context->getExtensions().textureBorderClamp)
5870 {
Jamie Madille0472f32018-11-27 16:32:45 -05005871 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005872 return false;
5873 }
5874 if (!vectorParams)
5875 {
Jamie Madille0472f32018-11-27 16:32:45 -05005876 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02005877 return false;
5878 }
5879 break;
5880
Jamie Madillbe849e42017-05-02 15:49:00 -04005881 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005882 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005883 return false;
5884 }
5885
5886 return true;
5887}
5888
Till Rathmannb8543632018-10-02 19:46:14 +02005889template bool ValidateTexParameterBase(Context *,
5890 TextureType,
5891 GLenum,
5892 GLsizei,
5893 bool,
5894 const GLfloat *);
5895template bool ValidateTexParameterBase(Context *,
5896 TextureType,
5897 GLenum,
5898 GLsizei,
5899 bool,
5900 const GLint *);
5901template bool ValidateTexParameterBase(Context *,
5902 TextureType,
5903 GLenum,
5904 GLsizei,
5905 bool,
5906 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04005907
Jamie Madill5b772312018-03-08 20:28:32 -05005908bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04005909{
5910 if (index >= MAX_VERTEX_ATTRIBS)
5911 {
Jamie Madille0472f32018-11-27 16:32:45 -05005912 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04005913 return false;
5914 }
5915
5916 return true;
5917}
5918
5919bool ValidateGetActiveUniformBlockivBase(Context *context,
5920 GLuint program,
5921 GLuint uniformBlockIndex,
5922 GLenum pname,
5923 GLsizei *length)
5924{
5925 if (length)
5926 {
5927 *length = 0;
5928 }
5929
5930 if (context->getClientMajorVersion() < 3)
5931 {
Jamie Madille0472f32018-11-27 16:32:45 -05005932 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04005933 return false;
5934 }
5935
5936 Program *programObject = GetValidProgram(context, program);
5937 if (!programObject)
5938 {
5939 return false;
5940 }
5941
5942 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
5943 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005944 context->validationError(GL_INVALID_VALUE, kIndexExceedsActiveUniformBlockCount);
Jamie Madill12e957f2017-08-26 21:42:26 -04005945 return false;
5946 }
5947
5948 switch (pname)
5949 {
5950 case GL_UNIFORM_BLOCK_BINDING:
5951 case GL_UNIFORM_BLOCK_DATA_SIZE:
5952 case GL_UNIFORM_BLOCK_NAME_LENGTH:
5953 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
5954 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
5955 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
5956 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
5957 break;
5958
5959 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005960 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04005961 return false;
5962 }
5963
5964 if (length)
5965 {
5966 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
5967 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08005968 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04005969 programObject->getUniformBlockByIndex(uniformBlockIndex);
5970 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
5971 }
5972 else
5973 {
5974 *length = 1;
5975 }
5976 }
5977
5978 return true;
5979}
5980
Jamie Madill9696d072017-08-26 23:19:57 -04005981template <typename ParamType>
5982bool ValidateSamplerParameterBase(Context *context,
5983 GLuint sampler,
5984 GLenum pname,
5985 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005986 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04005987 ParamType *params)
5988{
5989 if (context->getClientMajorVersion() < 3)
5990 {
Jamie Madille0472f32018-11-27 16:32:45 -05005991 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04005992 return false;
5993 }
5994
5995 if (!context->isSampler(sampler))
5996 {
Jamie Madille0472f32018-11-27 16:32:45 -05005997 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04005998 return false;
5999 }
6000
Till Rathmannb8543632018-10-02 19:46:14 +02006001 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006002 if (bufSize >= 0 && bufSize < minBufSize)
6003 {
Jamie Madille0472f32018-11-27 16:32:45 -05006004 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006005 return false;
6006 }
6007
6008 switch (pname)
6009 {
6010 case GL_TEXTURE_WRAP_S:
6011 case GL_TEXTURE_WRAP_T:
6012 case GL_TEXTURE_WRAP_R:
6013 if (!ValidateTextureWrapModeValue(context, params, false))
6014 {
6015 return false;
6016 }
6017 break;
6018
6019 case GL_TEXTURE_MIN_FILTER:
6020 if (!ValidateTextureMinFilterValue(context, params, false))
6021 {
6022 return false;
6023 }
6024 break;
6025
6026 case GL_TEXTURE_MAG_FILTER:
6027 if (!ValidateTextureMagFilterValue(context, params))
6028 {
6029 return false;
6030 }
6031 break;
6032
6033 case GL_TEXTURE_MIN_LOD:
6034 case GL_TEXTURE_MAX_LOD:
6035 // any value is permissible
6036 break;
6037
6038 case GL_TEXTURE_COMPARE_MODE:
6039 if (!ValidateTextureCompareModeValue(context, params))
6040 {
6041 return false;
6042 }
6043 break;
6044
6045 case GL_TEXTURE_COMPARE_FUNC:
6046 if (!ValidateTextureCompareFuncValue(context, params))
6047 {
6048 return false;
6049 }
6050 break;
6051
6052 case GL_TEXTURE_SRGB_DECODE_EXT:
6053 if (!ValidateTextureSRGBDecodeValue(context, params))
6054 {
6055 return false;
6056 }
6057 break;
6058
Luc Ferron1b1a8642018-01-23 15:12:01 -05006059 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6060 {
6061 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6062 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6063 {
6064 return false;
6065 }
6066 }
6067 break;
6068
Till Rathmannb8543632018-10-02 19:46:14 +02006069 case GL_TEXTURE_BORDER_COLOR:
6070 if (!context->getExtensions().textureBorderClamp)
6071 {
Jamie Madille0472f32018-11-27 16:32:45 -05006072 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006073 return false;
6074 }
6075 if (!vectorParams)
6076 {
Jamie Madille0472f32018-11-27 16:32:45 -05006077 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006078 return false;
6079 }
6080 break;
6081
Jamie Madill9696d072017-08-26 23:19:57 -04006082 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006083 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006084 return false;
6085 }
6086
6087 return true;
6088}
6089
Till Rathmannb8543632018-10-02 19:46:14 +02006090template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6091template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6092template bool ValidateSamplerParameterBase(Context *,
6093 GLuint,
6094 GLenum,
6095 GLsizei,
6096 bool,
6097 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006098
6099bool ValidateGetSamplerParameterBase(Context *context,
6100 GLuint sampler,
6101 GLenum pname,
6102 GLsizei *length)
6103{
6104 if (length)
6105 {
6106 *length = 0;
6107 }
6108
6109 if (context->getClientMajorVersion() < 3)
6110 {
Jamie Madille0472f32018-11-27 16:32:45 -05006111 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006112 return false;
6113 }
6114
6115 if (!context->isSampler(sampler))
6116 {
Jamie Madille0472f32018-11-27 16:32:45 -05006117 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006118 return false;
6119 }
6120
6121 switch (pname)
6122 {
6123 case GL_TEXTURE_WRAP_S:
6124 case GL_TEXTURE_WRAP_T:
6125 case GL_TEXTURE_WRAP_R:
6126 case GL_TEXTURE_MIN_FILTER:
6127 case GL_TEXTURE_MAG_FILTER:
6128 case GL_TEXTURE_MIN_LOD:
6129 case GL_TEXTURE_MAX_LOD:
6130 case GL_TEXTURE_COMPARE_MODE:
6131 case GL_TEXTURE_COMPARE_FUNC:
6132 break;
6133
Luc Ferron1b1a8642018-01-23 15:12:01 -05006134 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6135 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6136 {
6137 return false;
6138 }
6139 break;
6140
Jamie Madill9696d072017-08-26 23:19:57 -04006141 case GL_TEXTURE_SRGB_DECODE_EXT:
6142 if (!context->getExtensions().textureSRGBDecode)
6143 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006144 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006145 return false;
6146 }
6147 break;
6148
Till Rathmannb8543632018-10-02 19:46:14 +02006149 case GL_TEXTURE_BORDER_COLOR:
6150 if (!context->getExtensions().textureBorderClamp)
6151 {
Jamie Madille0472f32018-11-27 16:32:45 -05006152 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006153 return false;
6154 }
6155 break;
6156
Jamie Madill9696d072017-08-26 23:19:57 -04006157 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006158 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006159 return false;
6160 }
6161
6162 if (length)
6163 {
Till Rathmannb8543632018-10-02 19:46:14 +02006164 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006165 }
6166 return true;
6167}
6168
6169bool ValidateGetInternalFormativBase(Context *context,
6170 GLenum target,
6171 GLenum internalformat,
6172 GLenum pname,
6173 GLsizei bufSize,
6174 GLsizei *numParams)
6175{
6176 if (numParams)
6177 {
6178 *numParams = 0;
6179 }
6180
6181 if (context->getClientMajorVersion() < 3)
6182 {
Jamie Madille0472f32018-11-27 16:32:45 -05006183 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006184 return false;
6185 }
6186
6187 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006188 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006189 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006190 context->validationError(GL_INVALID_ENUM, kFormatNotRenderable);
Jamie Madill9696d072017-08-26 23:19:57 -04006191 return false;
6192 }
6193
6194 switch (target)
6195 {
6196 case GL_RENDERBUFFER:
6197 break;
6198
6199 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006200 if (context->getClientVersion() < ES_3_1 &&
6201 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006202 {
Jamie Madill610640f2018-11-21 17:28:41 -05006203 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006204 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006205 return false;
6206 }
6207 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006208 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6209 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006210 {
Jamie Madille0472f32018-11-27 16:32:45 -05006211 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006212 return false;
6213 }
6214 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006215 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006216 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006217 return false;
6218 }
6219
6220 if (bufSize < 0)
6221 {
Jamie Madille0472f32018-11-27 16:32:45 -05006222 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006223 return false;
6224 }
6225
6226 GLsizei maxWriteParams = 0;
6227 switch (pname)
6228 {
6229 case GL_NUM_SAMPLE_COUNTS:
6230 maxWriteParams = 1;
6231 break;
6232
6233 case GL_SAMPLES:
6234 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6235 break;
6236
6237 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006238 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006239 return false;
6240 }
6241
6242 if (numParams)
6243 {
6244 // glGetInternalFormativ will not overflow bufSize
6245 *numParams = std::min(bufSize, maxWriteParams);
6246 }
6247
6248 return true;
6249}
6250
Jamie Madille98b1b52018-03-08 09:47:23 -05006251bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6252{
Jamie Madill427064d2018-04-13 16:20:34 -04006253 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006254 {
Jamie Madille0472f32018-11-27 16:32:45 -05006255 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006256 return false;
6257 }
6258 return true;
6259}
6260
Lingfeng Yang038dd532018-03-29 17:31:52 -07006261bool ValidateMultitextureUnit(Context *context, GLenum texture)
6262{
6263 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6264 {
Jamie Madille0472f32018-11-27 16:32:45 -05006265 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006266 return false;
6267 }
6268 return true;
6269}
6270
Olli Etuahod310a432018-08-24 15:40:23 +03006271bool ValidateTexStorageMultisample(Context *context,
6272 TextureType target,
6273 GLsizei samples,
6274 GLint internalFormat,
6275 GLsizei width,
6276 GLsizei height)
6277{
6278 const Caps &caps = context->getCaps();
6279 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6280 static_cast<GLuint>(height) > caps.max2DTextureSize)
6281 {
Jamie Madille0472f32018-11-27 16:32:45 -05006282 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006283 return false;
6284 }
6285
6286 if (samples == 0)
6287 {
Jamie Madille0472f32018-11-27 16:32:45 -05006288 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006289 return false;
6290 }
6291
6292 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6293 if (!formatCaps.textureAttachment)
6294 {
Jamie Madille0472f32018-11-27 16:32:45 -05006295 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006296 return false;
6297 }
6298
6299 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6300 // is one of the unsized base internalformats listed in table 8.11.
6301 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6302 if (formatInfo.internalFormat == GL_NONE)
6303 {
Jamie Madille0472f32018-11-27 16:32:45 -05006304 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006305 return false;
6306 }
6307
6308 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6309 {
Jamie Madille0472f32018-11-27 16:32:45 -05006310 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006311 return false;
6312 }
6313
6314 Texture *texture = context->getTargetTexture(target);
6315 if (!texture || texture->id() == 0)
6316 {
Jamie Madille0472f32018-11-27 16:32:45 -05006317 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006318 return false;
6319 }
6320
6321 if (texture->getImmutableFormat())
6322 {
Jamie Madille0472f32018-11-27 16:32:45 -05006323 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006324 return false;
6325 }
6326 return true;
6327}
6328
Yizhou Jiang7818a852018-09-06 15:02:04 +08006329bool ValidateTexStorage2DMultisampleBase(Context *context,
6330 TextureType target,
6331 GLsizei samples,
6332 GLint internalFormat,
6333 GLsizei width,
6334 GLsizei height)
6335{
6336 if (target != TextureType::_2DMultisample)
6337 {
Jamie Madille0472f32018-11-27 16:32:45 -05006338 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006339 return false;
6340 }
6341
6342 if (width < 1 || height < 1)
6343 {
Jamie Madille0472f32018-11-27 16:32:45 -05006344 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006345 return false;
6346 }
6347
6348 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6349}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006350
6351bool ValidateGetTexLevelParameterBase(Context *context,
6352 TextureTarget target,
6353 GLint level,
6354 GLenum pname,
6355 GLsizei *length)
6356{
6357
6358 if (length)
6359 {
6360 *length = 0;
6361 }
6362
6363 TextureType type = TextureTargetToType(target);
6364
6365 if (!ValidTexLevelDestinationTarget(context, type))
6366 {
Jamie Madille0472f32018-11-27 16:32:45 -05006367 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006368 return false;
6369 }
6370
6371 if (context->getTargetTexture(type) == nullptr)
6372 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006373 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006374 return false;
6375 }
6376
6377 if (!ValidMipLevel(context, type, level))
6378 {
Jamie Madille0472f32018-11-27 16:32:45 -05006379 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006380 return false;
6381 }
6382
6383 switch (pname)
6384 {
6385 case GL_TEXTURE_RED_TYPE:
6386 case GL_TEXTURE_GREEN_TYPE:
6387 case GL_TEXTURE_BLUE_TYPE:
6388 case GL_TEXTURE_ALPHA_TYPE:
6389 case GL_TEXTURE_DEPTH_TYPE:
6390 break;
6391 case GL_TEXTURE_RED_SIZE:
6392 case GL_TEXTURE_GREEN_SIZE:
6393 case GL_TEXTURE_BLUE_SIZE:
6394 case GL_TEXTURE_ALPHA_SIZE:
6395 case GL_TEXTURE_DEPTH_SIZE:
6396 case GL_TEXTURE_STENCIL_SIZE:
6397 case GL_TEXTURE_SHARED_SIZE:
6398 break;
6399 case GL_TEXTURE_INTERNAL_FORMAT:
6400 case GL_TEXTURE_WIDTH:
6401 case GL_TEXTURE_HEIGHT:
6402 case GL_TEXTURE_DEPTH:
6403 break;
6404 case GL_TEXTURE_SAMPLES:
6405 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6406 break;
6407 case GL_TEXTURE_COMPRESSED:
6408 break;
6409 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006410 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006411 return false;
6412 }
6413
6414 if (length)
6415 {
6416 *length = 1;
6417 }
6418 return true;
6419}
Yizhou Jiang7310da32018-11-05 14:40:01 +08006420
6421bool ValidateGetMultisamplefvBase(Context *context, GLenum pname, GLuint index, GLfloat *val)
6422{
6423 if (pname != GL_SAMPLE_POSITION)
6424 {
6425 context->validationError(GL_INVALID_ENUM, kInvalidPname);
6426 return false;
6427 }
6428
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006429 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
Yizhou Jiang7310da32018-11-05 14:40:01 +08006430 GLint samples = framebuffer->getSamples(context);
6431
6432 if (index >= static_cast<GLuint>(samples))
6433 {
6434 context->validationError(GL_INVALID_VALUE, kIndexExceedsSamples);
6435 return false;
6436 }
6437
6438 return true;
6439}
6440
6441bool ValidateSampleMaskiBase(Context *context, GLuint maskNumber, GLbitfield mask)
6442{
6443 if (maskNumber >= context->getCaps().maxSampleMaskWords)
6444 {
6445 context->validationError(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
6446 return false;
6447 }
6448
6449 return true;
6450}
Jamie Madill9fa54ea2019-01-02 18:38:33 -05006451
6452void RecordDrawAttribsError(Context *context)
6453{
6454 // An overflow can happen when adding the offset. Check against a special constant.
6455 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
6456 VertexAttribute::kIntegerOverflow ||
6457 context->getStateCache().getInstancedVertexElementLimit() ==
6458 VertexAttribute::kIntegerOverflow)
6459 {
6460 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
6461 }
6462 else
6463 {
6464 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
6465 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
6466 context->validationError(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
6467 }
6468}
Jamie Madillc29968b2016-01-20 11:17:23 -05006469} // namespace gl