blob: 387534910d6c6590e359cf44af93cceac9ca08b9 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES.h: Validation functions for generic OpenGL ES entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES.h"
Jamie Madille2e406c2016-06-02 13:04:10 -040010
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Context.h"
Geoff Langa8406172015-07-21 16:53:39 -040012#include "libANGLE/Display.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070013#include "libANGLE/ErrorStrings.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050014#include "libANGLE/Framebuffer.h"
15#include "libANGLE/FramebufferAttachment.h"
Geoff Langa8406172015-07-21 16:53:39 -040016#include "libANGLE/Image.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050017#include "libANGLE/Program.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040018#include "libANGLE/Query.h"
19#include "libANGLE/Texture.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/TransformFeedback.h"
21#include "libANGLE/VertexArray.h"
James Darpinian30b604d2018-03-12 17:26:57 -070022#include "libANGLE/angletypes.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/formatutils.h"
jchen10a99ed552017-09-22 08:10:32 +080024#include "libANGLE/queryconversions.h"
Lingfeng Yangf97641c2018-06-21 19:22:45 -070025#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040026#include "libANGLE/validationES2.h"
27#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040028
29#include "common/mathutil.h"
30#include "common/utilities.h"
31
Jamie Madille2e406c2016-06-02 13:04:10 -040032using namespace angle;
33
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034namespace gl
35{
Jamie Madill1ca74672015-07-21 15:14:11 -040036namespace
37{
Luc Ferron9dbaeba2018-02-01 07:26:59 -050038bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
39{
40 // List of compressed format that require that the texture size is smaller than or a multiple of
41 // the compressed block size.
42 switch (internalFormat)
43 {
44 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
45 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
46 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
47 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
48 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
49 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
50 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
51 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
52 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
53 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
54 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
55 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
56 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
57 case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
58 case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
59 return true;
jchen10a99ed552017-09-22 08:10:32 +080060
Luc Ferron9dbaeba2018-02-01 07:26:59 -050061 default:
62 return false;
63 }
64}
65bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
66{
67 // Compressed sub textures have additional formats that requires exact size.
68 // ES 3.1, Section 8.7, Page 171
69 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
70 IsETC2EACFormat(internalFormat);
71}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030072
73bool DifferenceCanOverflow(GLint a, GLint b)
74{
75 CheckedNumeric<GLint> checkedA(a);
76 checkedA -= b;
77 // Use negation to make sure that the difference can't overflow regardless of the order.
78 checkedA = -checkedA;
79 return !checkedA.IsValid();
80}
81
Jamie Madill16e28fd2018-09-12 11:03:05 -040082bool ValidateDrawAttribsImpl(Context *context, GLint primcount, GLint maxVertex)
Jamie Madill1ca74672015-07-21 15:14:11 -040083{
Jamie Madill51af38b2018-04-15 08:50:56 -040084 // If we're drawing zero vertices, we have enough data.
Jamie Madill2da53562018-08-01 11:34:47 -040085 ASSERT(primcount > 0);
Jamie Madill51af38b2018-04-15 08:50:56 -040086
Jamie Madill88602e62018-08-08 12:49:30 -040087 // An overflow can happen when adding the offset. Check against a special constant.
88 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
89 VertexAttribute::kIntegerOverflow ||
90 context->getStateCache().getInstancedVertexElementLimit() ==
91 VertexAttribute::kIntegerOverflow)
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040092 {
93 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
94 return false;
95 }
96
97 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
98 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
99 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientVertexBufferSize);
100 return false;
Jamie Madill1ca74672015-07-21 15:14:11 -0400101}
102
Jamie Madill16e28fd2018-09-12 11:03:05 -0400103ANGLE_INLINE bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex)
104{
105 if (maxVertex <= context->getStateCache().getNonInstancedVertexElementLimit() &&
106 (primcount - 1) <= context->getStateCache().getInstancedVertexElementLimit())
107 {
108 return true;
109 }
110 else
111 {
112 return ValidateDrawAttribsImpl(context, primcount, maxVertex);
113 }
114}
115
Jamie Madill5b772312018-03-08 20:28:32 -0500116bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -0400117{
118 switch (type)
119 {
120 // Types referenced in Table 3.4 of the ES 2.0.25 spec
121 case GL_UNSIGNED_BYTE:
122 case GL_UNSIGNED_SHORT_4_4_4_4:
123 case GL_UNSIGNED_SHORT_5_5_5_1:
124 case GL_UNSIGNED_SHORT_5_6_5:
125 return context->getClientVersion() >= ES_2_0;
126
127 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
128 case GL_BYTE:
129 case GL_INT:
130 case GL_SHORT:
131 case GL_UNSIGNED_INT:
132 case GL_UNSIGNED_INT_10F_11F_11F_REV:
133 case GL_UNSIGNED_INT_24_8:
134 case GL_UNSIGNED_INT_2_10_10_10_REV:
135 case GL_UNSIGNED_INT_5_9_9_9_REV:
136 case GL_UNSIGNED_SHORT:
137 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
138 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
139 return context->getClientVersion() >= ES_3_0;
140
141 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400142 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
143 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400144
145 case GL_HALF_FLOAT:
146 return context->getClientVersion() >= ES_3_0 ||
147 context->getExtensions().textureHalfFloat;
148
149 case GL_HALF_FLOAT_OES:
150 return context->getExtensions().colorBufferHalfFloat;
151
152 default:
153 return false;
154 }
155}
156
Jamie Madill5b772312018-03-08 20:28:32 -0500157bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400158{
159 switch (format)
160 {
161 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
162 case GL_RGBA:
163 case GL_RGB:
164 case GL_ALPHA:
165 return context->getClientVersion() >= ES_2_0;
166
167 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
168 case GL_RG:
169 case GL_RED:
170 case GL_RGBA_INTEGER:
171 case GL_RGB_INTEGER:
172 case GL_RG_INTEGER:
173 case GL_RED_INTEGER:
174 return context->getClientVersion() >= ES_3_0;
175
176 case GL_SRGB_ALPHA_EXT:
177 case GL_SRGB_EXT:
178 return context->getExtensions().sRGB;
179
180 case GL_BGRA_EXT:
181 return context->getExtensions().readFormatBGRA;
182
183 default:
184 return false;
185 }
186}
187
Jamie Madill5b772312018-03-08 20:28:32 -0500188bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400189 GLenum framebufferComponentType,
190 GLenum format,
191 GLenum type)
192{
193 switch (framebufferComponentType)
194 {
195 case GL_UNSIGNED_NORMALIZED:
196 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
197 // ReadPixels with BGRA even if the extension is not present
198 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
199 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
200 type == GL_UNSIGNED_BYTE);
201
202 case GL_SIGNED_NORMALIZED:
203 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
204
205 case GL_INT:
206 return (format == GL_RGBA_INTEGER && type == GL_INT);
207
208 case GL_UNSIGNED_INT:
209 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
210
211 case GL_FLOAT:
212 return (format == GL_RGBA && type == GL_FLOAT);
213
214 default:
215 UNREACHABLE();
216 return false;
217 }
218}
219
Geoff Langc1984ed2016-10-07 12:41:00 -0400220template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400221bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400222{
223 switch (ConvertToGLenum(params[0]))
224 {
225 case GL_CLAMP_TO_EDGE:
226 break;
227
228 case GL_REPEAT:
229 case GL_MIRRORED_REPEAT:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400230 if (restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400231 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400232 // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
Brandon Jonesafa75152017-07-21 13:11:29 -0700233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400234 return false;
235 }
236 break;
237
238 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700239 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureWrap);
Geoff Langc1984ed2016-10-07 12:41:00 -0400240 return false;
241 }
242
243 return true;
244}
245
246template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400247bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400248{
249 switch (ConvertToGLenum(params[0]))
250 {
251 case GL_NEAREST:
252 case GL_LINEAR:
253 break;
254
255 case GL_NEAREST_MIPMAP_NEAREST:
256 case GL_LINEAR_MIPMAP_NEAREST:
257 case GL_NEAREST_MIPMAP_LINEAR:
258 case GL_LINEAR_MIPMAP_LINEAR:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400259 if (restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400260 {
261 // OES_EGL_image_external specifies this error.
Brandon Jonesafa75152017-07-21 13:11:29 -0700262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400263 return false;
264 }
265 break;
266
267 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700268 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400269 return false;
270 }
271
272 return true;
273}
274
275template <typename ParamType>
276bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
277{
278 switch (ConvertToGLenum(params[0]))
279 {
280 case GL_NEAREST:
281 case GL_LINEAR:
282 break;
283
284 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700285 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400286 return false;
287 }
288
289 return true;
290}
291
292template <typename ParamType>
293bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
294{
295 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
296 switch (ConvertToGLenum(params[0]))
297 {
298 case GL_NONE:
299 case GL_COMPARE_REF_TO_TEXTURE:
300 break;
301
302 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700303 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400304 return false;
305 }
306
307 return true;
308}
309
310template <typename ParamType>
311bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
312{
313 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
314 switch (ConvertToGLenum(params[0]))
315 {
316 case GL_LEQUAL:
317 case GL_GEQUAL:
318 case GL_LESS:
319 case GL_GREATER:
320 case GL_EQUAL:
321 case GL_NOTEQUAL:
322 case GL_ALWAYS:
323 case GL_NEVER:
324 break;
325
326 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700327 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400328 return false;
329 }
330
331 return true;
332}
333
334template <typename ParamType>
Geoff Lang81c6b572016-10-19 14:07:52 -0700335bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
336{
337 if (!context->getExtensions().textureSRGBDecode)
338 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700339 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Geoff Lang81c6b572016-10-19 14:07:52 -0700340 return false;
341 }
342
343 switch (ConvertToGLenum(params[0]))
344 {
345 case GL_DECODE_EXT:
346 case GL_SKIP_DECODE_EXT:
347 break;
348
349 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700350 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
Geoff Lang81c6b572016-10-19 14:07:52 -0700351 return false;
352 }
353
354 return true;
355}
356
Luc Ferron1b1a8642018-01-23 15:12:01 -0500357bool ValidateTextureMaxAnisotropyExtensionEnabled(Context *context)
358{
359 if (!context->getExtensions().textureFilterAnisotropic)
360 {
361 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
362 return false;
363 }
364
365 return true;
366}
367
368bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
369{
370 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
371 {
372 return false;
373 }
374
375 GLfloat largest = context->getExtensions().maxTextureAnisotropy;
376
377 if (paramValue < 1 || paramValue > largest)
378 {
379 ANGLE_VALIDATION_ERR(context, InvalidValue(), OutsideOfBounds);
380 return false;
381 }
382
383 return true;
384}
385
Jamie Madill5b772312018-03-08 20:28:32 -0500386bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
Geoff Lange0cff192017-05-30 13:04:56 -0400387{
Jamie Madill785e8a02018-10-04 17:42:00 -0400388 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lange0cff192017-05-30 13:04:56 -0400389 const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
390
Jamie Madille7d80f32018-08-08 15:49:23 -0400391 return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
392 framebuffer->getDrawBufferTypeMask().to_ulong(),
393 program->getActiveOutputVariables().to_ulong(),
394 framebuffer->getDrawBufferMask().to_ulong());
Geoff Lange0cff192017-05-30 13:04:56 -0400395}
396
Jamie Madill5b772312018-03-08 20:28:32 -0500397bool ValidateVertexShaderAttributeTypeMatch(Context *context)
Geoff Lang9ab5b822017-05-30 16:19:23 -0400398{
Lingfeng Yang038dd532018-03-29 17:31:52 -0700399 const auto &glState = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -0400400 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400401 const VertexArray *vao = context->getGLState().getVertexArray();
402
Brandon Jonesc405ae72017-12-06 14:15:03 -0800403 unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
404 unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
405 unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
406
407 vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
408 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
409 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
410
Jamie Madille7d80f32018-08-08 15:49:23 -0400411 return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
412 vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
413 0xFFFF);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400414}
415
Jamie Madill493f9572018-05-24 19:52:15 -0400416bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
417 PrimitiveMode geometryShaderInputPrimitiveType)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800418{
419 // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
Jamie Madill493f9572018-05-24 19:52:15 -0400420 switch (drawMode)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800421 {
Jamie Madill493f9572018-05-24 19:52:15 -0400422 case PrimitiveMode::Points:
423 return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
424 case PrimitiveMode::Lines:
425 case PrimitiveMode::LineStrip:
426 case PrimitiveMode::LineLoop:
427 return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
428 case PrimitiveMode::LinesAdjacency:
429 case PrimitiveMode::LineStripAdjacency:
430 return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
431 case PrimitiveMode::Triangles:
432 case PrimitiveMode::TriangleFan:
433 case PrimitiveMode::TriangleStrip:
434 return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
435 case PrimitiveMode::TrianglesAdjacency:
436 case PrimitiveMode::TriangleStripAdjacency:
437 return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
Jiawei Shaofccebff2018-03-08 13:51:02 +0800438 default:
439 UNREACHABLE();
440 return false;
441 }
442}
443
Lingfeng Yangf97641c2018-06-21 19:22:45 -0700444// GLES1 texture parameters are a small subset of the others
445bool IsValidGLES1TextureParameter(GLenum pname)
446{
447 switch (pname)
448 {
449 case GL_TEXTURE_MAG_FILTER:
450 case GL_TEXTURE_MIN_FILTER:
451 case GL_TEXTURE_WRAP_S:
452 case GL_TEXTURE_WRAP_T:
453 case GL_TEXTURE_WRAP_R:
454 case GL_GENERATE_MIPMAP:
455 case GL_TEXTURE_CROP_RECT_OES:
456 return true;
457 default:
458 return false;
459 }
460}
Geoff Langf41a7152016-09-19 15:11:17 -0400461} // anonymous namespace
462
Brandon Jonesd1049182018-03-28 10:02:20 -0700463void SetRobustLengthParam(GLsizei *length, GLsizei value)
464{
465 if (length)
466 {
467 *length = value;
468 }
469}
470
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500471bool IsETC2EACFormat(const GLenum format)
472{
473 // ES 3.1, Table 8.19
474 switch (format)
475 {
476 case GL_COMPRESSED_R11_EAC:
477 case GL_COMPRESSED_SIGNED_R11_EAC:
478 case GL_COMPRESSED_RG11_EAC:
479 case GL_COMPRESSED_SIGNED_RG11_EAC:
480 case GL_COMPRESSED_RGB8_ETC2:
481 case GL_COMPRESSED_SRGB8_ETC2:
482 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
483 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
484 case GL_COMPRESSED_RGBA8_ETC2_EAC:
485 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
486 return true;
487
488 default:
489 return false;
490 }
491}
492
Jamie Madill5b772312018-03-08 20:28:32 -0500493bool ValidTextureTarget(const Context *context, TextureType type)
Jamie Madill35d15012013-10-07 10:46:37 -0400494{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800495 switch (type)
Jamie Madill35d15012013-10-07 10:46:37 -0400496 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800497 case TextureType::_2D:
498 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800499 return true;
Jamie Madill35d15012013-10-07 10:46:37 -0400500
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800501 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400502 return context->getExtensions().textureRectangle;
503
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800504 case TextureType::_3D:
505 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800506 return (context->getClientMajorVersion() >= 3);
Jamie Madilld7460c72014-01-21 16:38:14 -0500507
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800508 case TextureType::_2DMultisample:
He Yunchaoced53ae2016-11-29 15:00:51 +0800509 return (context->getClientVersion() >= Version(3, 1));
Olli Etuahod310a432018-08-24 15:40:23 +0300510 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300511 return context->getExtensions().textureStorageMultisample2DArray;
Geoff Lang3b573612016-10-31 14:08:10 -0400512
He Yunchaoced53ae2016-11-29 15:00:51 +0800513 default:
514 return false;
Jamie Madilld7460c72014-01-21 16:38:14 -0500515 }
Jamie Madill35d15012013-10-07 10:46:37 -0400516}
517
Jamie Madill5b772312018-03-08 20:28:32 -0500518bool ValidTexture2DTarget(const Context *context, TextureType type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500519{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800520 switch (type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500521 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800522 case TextureType::_2D:
523 case TextureType::CubeMap:
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500524 return true;
525
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800526 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400527 return context->getExtensions().textureRectangle;
528
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500529 default:
530 return false;
531 }
532}
533
Jamie Madill5b772312018-03-08 20:28:32 -0500534bool ValidTexture3DTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500535{
536 switch (target)
537 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800538 case TextureType::_3D:
539 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +0300540 return (context->getClientMajorVersion() >= 3);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500541
542 default:
543 return false;
544 }
545}
546
Ian Ewellbda75592016-04-18 17:25:54 -0400547// Most texture GL calls are not compatible with external textures, so we have a separate validation
548// function for use in the GL calls that do
Jamie Madill5b772312018-03-08 20:28:32 -0500549bool ValidTextureExternalTarget(const Context *context, TextureType target)
Ian Ewellbda75592016-04-18 17:25:54 -0400550{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800551 return (target == TextureType::External) &&
Ian Ewellbda75592016-04-18 17:25:54 -0400552 (context->getExtensions().eglImageExternal ||
553 context->getExtensions().eglStreamConsumerExternal);
554}
555
Shannon Woods4dfed832014-03-17 20:03:39 -0400556// This function differs from ValidTextureTarget in that the target must be
557// usable as the destination of a 2D operation-- so a cube face is valid, but
558// GL_TEXTURE_CUBE_MAP is not.
Jamie Madill560a8d82014-05-21 13:06:20 -0400559// Note: duplicate of IsInternalTextureTarget
Jamie Madill5b772312018-03-08 20:28:32 -0500560bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
Shannon Woods4dfed832014-03-17 20:03:39 -0400561{
562 switch (target)
563 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800564 case TextureTarget::_2D:
565 case TextureTarget::CubeMapNegativeX:
566 case TextureTarget::CubeMapNegativeY:
567 case TextureTarget::CubeMapNegativeZ:
568 case TextureTarget::CubeMapPositiveX:
569 case TextureTarget::CubeMapPositiveY:
570 case TextureTarget::CubeMapPositiveZ:
He Yunchaoced53ae2016-11-29 15:00:51 +0800571 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800572 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400573 return context->getExtensions().textureRectangle;
He Yunchaoced53ae2016-11-29 15:00:51 +0800574 default:
575 return false;
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500576 }
577}
578
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800579bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400580 PrimitiveMode transformFeedbackPrimitiveMode,
581 PrimitiveMode renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800582{
583 ASSERT(context);
584
585 if (!context->getExtensions().geometryShader)
586 {
587 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
588 // that does not match the current transform feedback object's draw mode (if transform
589 // feedback is active), (3.0.2, section 2.14, pg 86)
590 return transformFeedbackPrimitiveMode == renderPrimitiveMode;
591 }
592
593 // [GL_EXT_geometry_shader] Table 12.1gs
Jamie Madill493f9572018-05-24 19:52:15 -0400594 switch (renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800595 {
Jamie Madill493f9572018-05-24 19:52:15 -0400596 case PrimitiveMode::Points:
597 return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
598 case PrimitiveMode::Lines:
599 case PrimitiveMode::LineStrip:
600 case PrimitiveMode::LineLoop:
601 return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
602 case PrimitiveMode::Triangles:
603 case PrimitiveMode::TriangleFan:
604 case PrimitiveMode::TriangleStrip:
605 return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800606 default:
607 UNREACHABLE();
608 return false;
609 }
610}
611
Jamie Madill5b772312018-03-08 20:28:32 -0500612bool ValidateDrawElementsInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400613 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400614 GLsizei count,
615 GLenum type,
616 const GLvoid *indices,
617 GLsizei primcount)
618{
619 if (primcount < 0)
620 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700621 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400622 return false;
623 }
624
625 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount))
626 {
627 return false;
628 }
629
Jamie Madill9fdaa492018-02-16 10:52:11 -0500630 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400631}
632
633bool ValidateDrawArraysInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400634 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400635 GLint first,
636 GLsizei count,
637 GLsizei primcount)
638{
639 if (primcount < 0)
640 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700641 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644
645 if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
646 {
647 return false;
648 }
649
Jamie Madill9fdaa492018-02-16 10:52:11 -0500650 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400651}
652
Jamie Madill5b772312018-03-08 20:28:32 -0500653bool ValidateDrawInstancedANGLE(Context *context)
Jamie Madillbe849e42017-05-02 15:49:00 -0400654{
655 // Verify there is at least one active attribute with a divisor of zero
656 const State &state = context->getGLState();
657
Jamie Madill785e8a02018-10-04 17:42:00 -0400658 Program *program = state.getLinkedProgram(context);
Jamie Madillbe849e42017-05-02 15:49:00 -0400659
660 const auto &attribs = state.getVertexArray()->getVertexAttributes();
661 const auto &bindings = state.getVertexArray()->getVertexBindings();
662 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
663 {
664 const VertexAttribute &attrib = attribs[attributeIndex];
665 const VertexBinding &binding = bindings[attrib.bindingIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +0300666 if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400667 {
668 return true;
669 }
670 }
671
Brandon Jonesafa75152017-07-21 13:11:29 -0700672 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoZeroDivisor);
Jamie Madillbe849e42017-05-02 15:49:00 -0400673 return false;
674}
675
Jamie Madill5b772312018-03-08 20:28:32 -0500676bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500677{
678 switch (target)
679 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800680 case TextureType::_3D:
681 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800682 return true;
683 default:
684 return false;
Shannon Woods4dfed832014-03-17 20:03:39 -0400685 }
686}
687
Jamie Madill5b772312018-03-08 20:28:32 -0500688bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
He Yunchao11b038b2016-11-22 21:24:04 +0800689{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800690 switch (type)
He Yunchao11b038b2016-11-22 21:24:04 +0800691 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800692 case TextureType::_2D:
693 case TextureType::_2DArray:
694 case TextureType::_2DMultisample:
695 case TextureType::CubeMap:
696 case TextureType::_3D:
He Yunchao11b038b2016-11-22 21:24:04 +0800697 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800698 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400699 return context->getExtensions().textureRectangle;
Olli Etuahod310a432018-08-24 15:40:23 +0300700 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300701 return context->getExtensions().textureStorageMultisample2DArray;
He Yunchao11b038b2016-11-22 21:24:04 +0800702 default:
703 return false;
704 }
705}
706
Jamie Madill5b772312018-03-08 20:28:32 -0500707bool ValidFramebufferTarget(const Context *context, GLenum target)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500708{
He Yunchaoced53ae2016-11-29 15:00:51 +0800709 static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
710 GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
Geoff Langd4475812015-03-18 10:53:05 -0400711 "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500712
713 switch (target)
714 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800715 case GL_FRAMEBUFFER:
716 return true;
Geoff Lange8afa902017-09-27 15:00:43 -0400717
He Yunchaoced53ae2016-11-29 15:00:51 +0800718 case GL_READ_FRAMEBUFFER:
He Yunchaoced53ae2016-11-29 15:00:51 +0800719 case GL_DRAW_FRAMEBUFFER:
Geoff Lange8afa902017-09-27 15:00:43 -0400720 return (context->getExtensions().framebufferBlit ||
721 context->getClientMajorVersion() >= 3);
722
He Yunchaoced53ae2016-11-29 15:00:51 +0800723 default:
724 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500725 }
726}
727
Jamie Madill5b772312018-03-08 20:28:32 -0500728bool ValidMipLevel(const Context *context, TextureType type, GLint level)
Geoff Langce635692013-09-24 13:56:32 -0400729{
Jamie Madillc29968b2016-01-20 11:17:23 -0500730 const auto &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -0400731 size_t maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800732 switch (type)
Geoff Langce635692013-09-24 13:56:32 -0400733 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800734 case TextureType::_2D:
735 case TextureType::_2DArray:
736 case TextureType::_2DMultisample:
Olli Etuahod310a432018-08-24 15:40:23 +0300737 case TextureType::_2DMultisampleArray:
738 // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
739 // level-of-detail" for multisample textures should be. Could maybe make it zero.
Jamie Madillc29968b2016-01-20 11:17:23 -0500740 maxDimension = caps.max2DTextureSize;
741 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800742 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800743 maxDimension = caps.maxCubeMapTextureSize;
744 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800745 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400746 return level == 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800747 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800748 maxDimension = caps.max3DTextureSize;
749 break;
He Yunchaoced53ae2016-11-29 15:00:51 +0800750 default:
751 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400752 }
753
Jamie Madill43da7c42018-08-01 11:34:49 -0400754 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400755}
756
Jamie Madill5b772312018-03-08 20:28:32 -0500757bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800758 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700759 GLint level,
760 GLsizei width,
761 GLsizei height,
762 GLsizei depth,
763 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400764{
Brandon Jones6cad5662017-06-14 13:25:13 -0700765 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400766 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700767 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400768 return false;
769 }
Austin Kinross08528e12015-10-07 16:24:40 -0700770 // TexSubImage parameters can be NPOT without textureNPOT extension,
771 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500772 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500773 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500774 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400775 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400776 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700777 ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400778 return false;
779 }
780
781 if (!ValidMipLevel(context, target, level))
782 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700783 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400784 return false;
785 }
786
787 return true;
788}
789
Geoff Lang966c9402017-04-18 12:38:27 -0400790bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
791{
792 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
793 (size % blockSize == 0);
794}
795
Jamie Madill5b772312018-03-08 20:28:32 -0500796bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500797 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400798 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500799 GLsizei width,
800 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400801{
Jamie Madill43da7c42018-08-01 11:34:49 -0400802 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400803 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400804 {
805 return false;
806 }
807
Geoff Lang966c9402017-04-18 12:38:27 -0400808 if (width < 0 || height < 0)
809 {
810 return false;
811 }
812
813 if (CompressedTextureFormatRequiresExactSize(internalFormat))
814 {
815 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
816 // block size for level 0 but WebGL disallows this.
817 bool smallerThanBlockSizeAllowed =
818 level > 0 || !context->getExtensions().webglCompatibility;
819
820 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
821 smallerThanBlockSizeAllowed) ||
822 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
823 smallerThanBlockSizeAllowed))
824 {
825 return false;
826 }
827 }
828
829 return true;
830}
831
Jamie Madill5b772312018-03-08 20:28:32 -0500832bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400833 GLenum internalFormat,
834 GLint xoffset,
835 GLint yoffset,
836 GLsizei width,
837 GLsizei height,
838 size_t textureWidth,
839 size_t textureHeight)
840{
Jamie Madill43da7c42018-08-01 11:34:49 -0400841 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400842 if (!formatInfo.compressed)
843 {
844 return false;
845 }
846
Geoff Lang44ff5a72017-02-03 15:15:43 -0500847 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400848 {
849 return false;
850 }
851
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500852 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400853 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500854 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400855 yoffset % formatInfo.compressedBlockHeight != 0)
856 {
857 return false;
858 }
859
860 // Allowed to either have data that is a multiple of block size or is smaller than the block
861 // size but fills the entire mip
862 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
863 static_cast<size_t>(width) == textureWidth &&
864 static_cast<size_t>(height) == textureHeight;
865 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
866 (height % formatInfo.compressedBlockHeight) == 0;
867 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400868 {
869 return false;
870 }
871 }
872
Geoff Langd4f180b2013-09-24 13:57:44 -0400873 return true;
874}
875
Jamie Madill5b772312018-03-08 20:28:32 -0500876bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800877 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400878 GLsizei width,
879 GLsizei height,
880 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400881 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400882 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400883 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400884 GLsizei imageSize)
885{
Jamie Madill43da7c42018-08-01 11:34:49 -0400886 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400887 if (pixelUnpackBuffer == nullptr && imageSize < 0)
888 {
889 // Checks are not required
890 return true;
891 }
892
893 // ...the data would be unpacked from the buffer object such that the memory reads required
894 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400895 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400896 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400897 const Extents size(width, height, depth);
Geoff Langff5b2d52016-09-07 11:32:23 -0400898 const auto &unpack = context->getGLState().getUnpackState();
899
Jamie Madill7f232932018-09-12 11:03:06 -0400900 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
901 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400902 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400903 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400904 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400905 return false;
906 }
907
Geoff Langff5b2d52016-09-07 11:32:23 -0400908 if (pixelUnpackBuffer)
909 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400910 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400911 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
912 checkedEndByte += checkedOffset;
913
914 if (!checkedEndByte.IsValid() ||
915 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
916 {
917 // Overflow past the end of the buffer
Jamie Madillca2ff382018-07-11 09:01:17 -0400918 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400919 return false;
920 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800921 if (context->getExtensions().webglCompatibility &&
922 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
923 {
924 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
925 PixelUnpackBufferBoundForTransformFeedback);
926 return false;
927 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400928 }
929 else
930 {
931 ASSERT(imageSize >= 0);
932 if (pixels == nullptr && imageSize != 0)
933 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500934 context->handleError(InvalidOperation()
935 << "imageSize must be 0 if no texture data is provided.");
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400936 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400937 }
938
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400939 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400940 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500941 context->handleError(InvalidOperation() << "imageSize must be at least " << endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400942 return false;
943 }
944 }
945
946 return true;
947}
948
Corentin Wallezad3ae902018-03-09 13:40:42 -0500949bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500950{
Geoff Lang37dde692014-01-31 16:34:54 -0500951 switch (queryType)
952 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500953 case QueryType::AnySamples:
954 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400955 return context->getClientMajorVersion() >= 3 ||
956 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500957 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800958 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500959 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800960 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500961 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800962 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500963 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800964 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800965 default:
966 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500967 }
968}
969
Jamie Madill5b772312018-03-08 20:28:32 -0500970bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400971 GLenum type,
972 GLboolean normalized,
973 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400974 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400975 bool pureInteger)
976{
977 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -0400978 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
979 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
980 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
981 // parameter exceeds 255.
982 constexpr GLsizei kMaxWebGLStride = 255;
983 if (stride > kMaxWebGLStride)
984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500985 context->handleError(InvalidValue()
986 << "Stride is over the maximum stride allowed by WebGL.");
Geoff Lang2d62ab72017-03-23 16:54:40 -0400987 return false;
988 }
989
990 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
991 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
992 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
993 // or an INVALID_OPERATION error is generated.
994 VertexFormatType internalType = GetVertexFormatType(type, normalized, 1, pureInteger);
995 size_t typeSize = GetVertexFormatTypeSize(internalType);
996
997 ASSERT(isPow2(typeSize) && typeSize > 0);
998 size_t sizeMask = (typeSize - 1);
999 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1000 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001001 ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001002 return false;
1003 }
1004
1005 if ((stride & sizeMask) != 0)
1006 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001007 ANGLE_VALIDATION_ERR(context, InvalidOperation(), StrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001008 return false;
1009 }
1010
1011 return true;
1012}
1013
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001014Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001015{
He Yunchaoced53ae2016-11-29 15:00:51 +08001016 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1017 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1018 // or program object and INVALID_OPERATION if the provided name identifies an object
1019 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001020
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001021 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001022
1023 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001024 {
Dian Xiang769769a2015-09-09 15:20:08 -07001025 if (context->getShader(id))
1026 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001027 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001028 }
1029 else
1030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001031 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001032 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001033 }
Dian Xiang769769a2015-09-09 15:20:08 -07001034
1035 return validProgram;
1036}
1037
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001038Program *GetValidProgram(Context *context, GLuint id)
1039{
1040 Program *program = GetValidProgramNoResolve(context, id);
1041 if (program)
1042 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001043 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001044 }
1045 return program;
1046}
1047
Jamie Madill5b772312018-03-08 20:28:32 -05001048Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001049{
1050 // See ValidProgram for spec details.
1051
1052 Shader *validShader = context->getShader(id);
1053
1054 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001055 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001056 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001058 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001059 }
1060 else
1061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001062 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001063 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001064 }
Dian Xiang769769a2015-09-09 15:20:08 -07001065
1066 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001067}
1068
Jamie Madill43da7c42018-08-01 11:34:49 -04001069bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001070{
Geoff Langfa125c92017-10-24 13:01:46 -04001071 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001072 {
Geoff Langfa125c92017-10-24 13:01:46 -04001073 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1074 {
1075 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
1076 return false;
1077 }
Jamie Madillb4472272014-07-03 10:38:55 -04001078
Geoff Langfa125c92017-10-24 13:01:46 -04001079 // Color attachment 0 is validated below because it is always valid
1080 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001081 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001082 {
Geoff Langfa125c92017-10-24 13:01:46 -04001083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001084 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001085 }
1086 }
1087 else
1088 {
1089 switch (attachment)
1090 {
Geoff Langfa125c92017-10-24 13:01:46 -04001091 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001092 case GL_DEPTH_ATTACHMENT:
1093 case GL_STENCIL_ATTACHMENT:
1094 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001095
He Yunchaoced53ae2016-11-29 15:00:51 +08001096 case GL_DEPTH_STENCIL_ATTACHMENT:
1097 if (!context->getExtensions().webglCompatibility &&
1098 context->getClientMajorVersion() < 3)
1099 {
Geoff Langfa125c92017-10-24 13:01:46 -04001100 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001101 return false;
1102 }
1103 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001104
He Yunchaoced53ae2016-11-29 15:00:51 +08001105 default:
Geoff Langfa125c92017-10-24 13:01:46 -04001106 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001107 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001108 }
1109 }
1110
1111 return true;
1112}
1113
Jamie Madill5b772312018-03-08 20:28:32 -05001114bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001115 GLenum target,
1116 GLsizei samples,
1117 GLenum internalformat,
1118 GLsizei width,
1119 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001120{
1121 switch (target)
1122 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001123 case GL_RENDERBUFFER:
1124 break;
1125 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001126 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001127 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 }
1129
1130 if (width < 0 || height < 0 || samples < 0)
1131 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001132 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001133 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001134 }
1135
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001136 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1137 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1138
1139 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001140 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001142 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001143 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001144 }
1145
1146 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1147 // 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 -08001148 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001149 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001150 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001151 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001152 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001153 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001154 }
1155
Geoff Langaae65a42014-05-26 12:43:44 -04001156 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001157 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001158 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001159 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001160 }
1161
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001162 GLuint handle = context->getGLState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001163 if (handle == 0)
1164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001166 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 }
1168
1169 return true;
1170}
1171
Jamie Madill43da7c42018-08-01 11:34:49 -04001172bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001173 GLenum target,
1174 GLenum attachment,
1175 GLenum renderbuffertarget,
1176 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001177{
Geoff Lange8afa902017-09-27 15:00:43 -04001178 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001179 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001180 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001181 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001182 }
1183
Jamie Madill43da7c42018-08-01 11:34:49 -04001184 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001185
Jamie Madill84115c92015-04-23 15:00:07 -04001186 ASSERT(framebuffer);
1187 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001188 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001189 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001190 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001191 }
1192
Jamie Madillb4472272014-07-03 10:38:55 -04001193 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001194 {
Jamie Madillb4472272014-07-03 10:38:55 -04001195 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001196 }
1197
Jamie Madillab9d82c2014-01-21 16:38:14 -05001198 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1199 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1200 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1201 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1202 if (renderbuffer != 0)
1203 {
1204 if (!context->getRenderbuffer(renderbuffer))
1205 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001206 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001207 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001208 }
1209 }
1210
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001211 return true;
1212}
1213
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001214bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001215 GLint srcX0,
1216 GLint srcY0,
1217 GLint srcX1,
1218 GLint srcY1,
1219 GLint dstX0,
1220 GLint dstY0,
1221 GLint dstX1,
1222 GLint dstY1,
1223 GLbitfield mask,
1224 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001225{
1226 switch (filter)
1227 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001228 case GL_NEAREST:
1229 break;
1230 case GL_LINEAR:
1231 break;
1232 default:
Olli Etuahof0e3c192018-08-15 13:37:21 +03001233 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001234 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001235 }
1236
1237 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1238 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001239 ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001240 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001241 }
1242
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001243 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1244 // color buffer, leaving only nearest being unfiltered from above
1245 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1246 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001247 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001248 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001249 }
1250
Jamie Madill7f232932018-09-12 11:03:06 -04001251 const auto &glState = context->getGLState();
1252 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1253 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001254
1255 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001256 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001257 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001258 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001259 }
1260
Jamie Madill427064d2018-04-13 16:20:34 -04001261 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001262 {
Jamie Madill48faf802014-11-06 15:27:22 -05001263 return false;
1264 }
1265
Jamie Madill427064d2018-04-13 16:20:34 -04001266 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001267 {
Jamie Madill48faf802014-11-06 15:27:22 -05001268 return false;
1269 }
1270
Qin Jiajiaaef92162018-02-27 13:51:44 +08001271 if (readFramebuffer->id() == drawFramebuffer->id())
1272 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001273 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001274 return false;
1275 }
1276
Jamie Madille98b1b52018-03-08 09:47:23 -05001277 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001278 {
Geoff Langb1196682014-07-23 13:47:29 -04001279 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001280 }
1281
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001282 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1283 // always run it in order to avoid triggering driver bugs.
1284 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1285 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001286 {
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001287 ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitDimensionsOutOfRange);
1288 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001289 }
1290
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001291 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1292
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001293 if (mask & GL_COLOR_BUFFER_BIT)
1294 {
Jamie Madill7f232932018-09-12 11:03:06 -04001295 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1296 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001297
He Yunchao66a41a22016-12-15 16:45:05 +08001298 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001299 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001300 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001301
Geoff Langa15472a2015-08-11 11:48:03 -04001302 for (size_t drawbufferIdx = 0;
1303 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001304 {
Geoff Langa15472a2015-08-11 11:48:03 -04001305 const FramebufferAttachment *attachment =
1306 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1307 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001308 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001309 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001310
Geoff Langb2f3d052013-08-13 12:49:27 -04001311 // The GL ES 3.0.2 spec (pg 193) states that:
1312 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001313 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1314 // as well
1315 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1316 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001317 // Changes with EXT_color_buffer_float:
1318 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001319 GLenum readComponentType = readFormat.info->componentType;
1320 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001322 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001323 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001324 drawComponentType == GL_SIGNED_NORMALIZED);
1325
1326 if (extensions.colorBufferFloat)
1327 {
1328 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1329 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1330
1331 if (readFixedOrFloat != drawFixedOrFloat)
1332 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001333 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1334 BlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001335 return false;
1336 }
1337 }
1338 else if (readFixedPoint != drawFixedPoint)
1339 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001340 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1341 BlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001342 return false;
1343 }
1344
1345 if (readComponentType == GL_UNSIGNED_INT &&
1346 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001347 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001348 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1349 BlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001350 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001351 }
1352
Jamie Madill6163c752015-12-07 16:32:59 -05001353 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001354 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001355 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1356 BlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001357 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001358 }
1359
Jamie Madilla3944d42016-07-22 22:13:26 -04001360 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001361 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001362 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001363 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1364 BlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001365 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001366 }
Geoff Lange4915782017-04-12 15:19:07 -04001367
1368 if (context->getExtensions().webglCompatibility &&
1369 *readColorBuffer == *attachment)
1370 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001372 return false;
1373 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 }
1375 }
1376
Jamie Madilla3944d42016-07-22 22:13:26 -04001377 if ((readFormat.info->componentType == GL_INT ||
1378 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1379 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001380 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001382 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001383 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001384 }
He Yunchao66a41a22016-12-15 16:45:05 +08001385 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1386 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1387 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1388 // situation is an application error that would lead to a crash in ANGLE.
1389 else if (drawFramebuffer->hasEnabledDrawBuffer())
1390 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001392 return false;
1393 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001394 }
1395
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001397 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1398 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001399 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001400 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001401 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001402 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001403 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001404 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001405 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001406
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001407 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001408 {
Kenneth Russell69382852017-07-21 16:38:44 -04001409 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001410 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001411 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1412 BlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001413 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001414 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001415
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001416 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001417 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001418 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1419 BlitMultisampledBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001420 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 }
Geoff Lange4915782017-04-12 15:19:07 -04001422
1423 if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer)
1424 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001426 return false;
1427 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001428 }
He Yunchao66a41a22016-12-15 16:45:05 +08001429 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1430 else if (drawBuffer)
1431 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001433 return false;
1434 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001435 }
1436 }
1437
Martin Radeva3ed4572017-07-27 18:29:37 +03001438 // ANGLE_multiview, Revision 1:
1439 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001440 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1441 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1442 // views in the current read framebuffer is more than one.
1443 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001444 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001445 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001446 return false;
1447 }
1448 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1449 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001450 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001451 return false;
1452 }
1453
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001454 return true;
1455}
1456
Jamie Madill4928b7c2017-06-20 12:57:39 -04001457bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001458 GLint x,
1459 GLint y,
1460 GLsizei width,
1461 GLsizei height,
1462 GLenum format,
1463 GLenum type,
1464 GLsizei bufSize,
1465 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001466 GLsizei *columns,
1467 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001468 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001469{
1470 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001471 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001472 return false;
1473 }
1474
Brandon Jonesd1049182018-03-28 10:02:20 -07001475 GLsizei writeLength = 0;
1476 GLsizei writeColumns = 0;
1477 GLsizei writeRows = 0;
1478
1479 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1480 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001481 {
Geoff Langb1196682014-07-23 13:47:29 -04001482 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001483 }
1484
Brandon Jonesd1049182018-03-28 10:02:20 -07001485 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001486 {
Geoff Langb1196682014-07-23 13:47:29 -04001487 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001488 }
1489
Brandon Jonesd1049182018-03-28 10:02:20 -07001490 SetRobustLengthParam(length, writeLength);
1491 SetRobustLengthParam(columns, writeColumns);
1492 SetRobustLengthParam(rows, writeRows);
1493
Jamie Madillc29968b2016-01-20 11:17:23 -05001494 return true;
1495}
1496
1497bool ValidateReadnPixelsEXT(Context *context,
1498 GLint x,
1499 GLint y,
1500 GLsizei width,
1501 GLsizei height,
1502 GLenum format,
1503 GLenum type,
1504 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001505 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001506{
1507 if (bufSize < 0)
1508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001509 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001510 return false;
1511 }
1512
Geoff Lang62fce5b2016-09-30 10:46:35 -04001513 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001514 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001515}
Jamie Madill26e91952014-03-05 15:01:27 -05001516
Jamie Madill4928b7c2017-06-20 12:57:39 -04001517bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001518 GLint x,
1519 GLint y,
1520 GLsizei width,
1521 GLsizei height,
1522 GLenum format,
1523 GLenum type,
1524 GLsizei bufSize,
1525 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001526 GLsizei *columns,
1527 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001528 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001529{
Brandon Jonesd1049182018-03-28 10:02:20 -07001530 GLsizei writeLength = 0;
1531 GLsizei writeColumns = 0;
1532 GLsizei writeRows = 0;
1533
Geoff Lang62fce5b2016-09-30 10:46:35 -04001534 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001535 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001536 return false;
1537 }
1538
Brandon Jonesd1049182018-03-28 10:02:20 -07001539 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1540 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001541 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001542 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001543 }
1544
Brandon Jonesd1049182018-03-28 10:02:20 -07001545 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001546 {
1547 return false;
1548 }
1549
Brandon Jonesd1049182018-03-28 10:02:20 -07001550 SetRobustLengthParam(length, writeLength);
1551 SetRobustLengthParam(columns, writeColumns);
1552 SetRobustLengthParam(rows, writeRows);
1553
Geoff Lang62fce5b2016-09-30 10:46:35 -04001554 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001555}
1556
Jamie Madill43da7c42018-08-01 11:34:49 -04001557bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001558{
1559 if (!context->getExtensions().occlusionQueryBoolean &&
1560 !context->getExtensions().disjointTimerQuery)
1561 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001562 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001563 return false;
1564 }
1565
Olli Etuaho41997e72016-03-10 13:38:39 +02001566 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001567}
1568
Jamie Madill43da7c42018-08-01 11:34:49 -04001569bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001570{
1571 if (!context->getExtensions().occlusionQueryBoolean &&
1572 !context->getExtensions().disjointTimerQuery)
1573 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001574 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001575 return false;
1576 }
1577
Olli Etuaho41997e72016-03-10 13:38:39 +02001578 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001579}
1580
Jamie Madill43da7c42018-08-01 11:34:49 -04001581bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001582{
1583 if (!context->getExtensions().occlusionQueryBoolean &&
1584 !context->getExtensions().disjointTimerQuery)
1585 {
1586 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
1587 return false;
1588 }
1589
1590 return true;
1591}
1592
Jamie Madill43da7c42018-08-01 11:34:49 -04001593bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001594{
1595 if (!ValidQueryType(context, target))
1596 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001598 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001599 }
1600
1601 if (id == 0)
1602 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001603 context->handleError(InvalidOperation() << "Query id is 0");
Geoff Langb1196682014-07-23 13:47:29 -04001604 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001605 }
1606
1607 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1608 // of zero, if the active query object name for <target> is non-zero (for the
1609 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1610 // the active query for either target is non-zero), if <id> is the name of an
1611 // existing query object whose type does not match <target>, or if <id> is the
1612 // active query object name for any query type, the error INVALID_OPERATION is
1613 // generated.
1614
1615 // Ensure no other queries are active
1616 // NOTE: If other queries than occlusion are supported, we will need to check
1617 // separately that:
1618 // a) The query ID passed is not the current active query for any target/type
1619 // b) There are no active queries for the requested target (and in the case
1620 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1621 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001622
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001623 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001624 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001625 context->handleError(InvalidOperation() << "Other query is active");
Geoff Langb1196682014-07-23 13:47:29 -04001626 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001627 }
1628
1629 Query *queryObject = context->getQuery(id, true, target);
1630
1631 // check that name was obtained with glGenQueries
1632 if (!queryObject)
1633 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001634 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001636 }
1637
1638 // check for type mismatch
1639 if (queryObject->getType() != target)
1640 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001641 context->handleError(InvalidOperation() << "Query type does not match target");
Geoff Langb1196682014-07-23 13:47:29 -04001642 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001643 }
1644
1645 return true;
1646}
1647
Jamie Madill43da7c42018-08-01 11:34:49 -04001648bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001649{
1650 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001651 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001652 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001653 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001654 return false;
1655 }
1656
1657 return ValidateBeginQueryBase(context, target, id);
1658}
1659
Jamie Madill43da7c42018-08-01 11:34:49 -04001660bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001661{
1662 if (!ValidQueryType(context, target))
1663 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001664 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001665 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001666 }
1667
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001668 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001669
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001670 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001671 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001672 context->handleError(InvalidOperation() << "Query target not active");
Geoff Langb1196682014-07-23 13:47:29 -04001673 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001674 }
1675
Jamie Madill45c785d2014-05-13 14:09:34 -04001676 return true;
1677}
1678
Jamie Madill43da7c42018-08-01 11:34:49 -04001679bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001680{
1681 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001682 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001683 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001684 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001685 return false;
1686 }
1687
1688 return ValidateEndQueryBase(context, target);
1689}
1690
Corentin Wallezad3ae902018-03-09 13:40:42 -05001691bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001692{
1693 if (!context->getExtensions().disjointTimerQuery)
1694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidOperation() << "Disjoint timer query not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001696 return false;
1697 }
1698
Corentin Wallezad3ae902018-03-09 13:40:42 -05001699 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001700 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001701 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001702 return false;
1703 }
1704
1705 Query *queryObject = context->getQuery(id, true, target);
1706 if (queryObject == nullptr)
1707 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001708 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001709 return false;
1710 }
1711
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001712 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001713 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001714 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001715 return false;
1716 }
1717
1718 return true;
1719}
1720
Corentin Wallezad3ae902018-03-09 13:40:42 -05001721bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001722{
Geoff Lang2186c382016-10-14 10:54:54 -04001723 if (numParams)
1724 {
1725 *numParams = 0;
1726 }
1727
Corentin Wallezad3ae902018-03-09 13:40:42 -05001728 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001729 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001730 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001731 return false;
1732 }
1733
1734 switch (pname)
1735 {
1736 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001737 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001739 context->handleError(InvalidEnum() << "Cannot use current query for timestamp");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001740 return false;
1741 }
1742 break;
1743 case GL_QUERY_COUNTER_BITS_EXT:
1744 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001745 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001746 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001747 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001748 return false;
1749 }
1750 break;
1751 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001752 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001753 return false;
1754 }
1755
Geoff Lang2186c382016-10-14 10:54:54 -04001756 if (numParams)
1757 {
1758 // All queries return only one value
1759 *numParams = 1;
1760 }
1761
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001762 return true;
1763}
1764
Corentin Wallezad3ae902018-03-09 13:40:42 -05001765bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001766{
1767 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001768 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001769 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001770 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001771 return false;
1772 }
1773
Geoff Lang2186c382016-10-14 10:54:54 -04001774 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001775}
1776
Geoff Lang2186c382016-10-14 10:54:54 -04001777bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001778 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001779 GLenum pname,
1780 GLsizei bufSize,
1781 GLsizei *length,
1782 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001783{
Geoff Lang2186c382016-10-14 10:54:54 -04001784 if (!ValidateRobustEntryPoint(context, bufSize))
1785 {
1786 return false;
1787 }
1788
Brandon Jonesd1049182018-03-28 10:02:20 -07001789 GLsizei numParams = 0;
1790
1791 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001792 {
1793 return false;
1794 }
1795
Brandon Jonesd1049182018-03-28 10:02:20 -07001796 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001797 {
1798 return false;
1799 }
1800
Brandon Jonesd1049182018-03-28 10:02:20 -07001801 SetRobustLengthParam(length, numParams);
1802
Geoff Lang2186c382016-10-14 10:54:54 -04001803 return true;
1804}
1805
1806bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1807{
1808 if (numParams)
1809 {
1810 *numParams = 0;
1811 }
1812
Corentin Wallezad3ae902018-03-09 13:40:42 -05001813 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001814
1815 if (!queryObject)
1816 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001817 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001818 return false;
1819 }
1820
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001821 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001822 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001823 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001824 return false;
1825 }
1826
1827 switch (pname)
1828 {
1829 case GL_QUERY_RESULT_EXT:
1830 case GL_QUERY_RESULT_AVAILABLE_EXT:
1831 break;
1832
1833 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001834 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001835 return false;
1836 }
1837
Geoff Lang2186c382016-10-14 10:54:54 -04001838 if (numParams)
1839 {
1840 *numParams = 1;
1841 }
1842
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001843 return true;
1844}
1845
1846bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1847{
1848 if (!context->getExtensions().disjointTimerQuery)
1849 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001850 context->handleError(InvalidOperation() << "Timer query extension not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001851 return false;
1852 }
Geoff Lang2186c382016-10-14 10:54:54 -04001853 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1854}
1855
1856bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1857 GLuint id,
1858 GLenum pname,
1859 GLsizei bufSize,
1860 GLsizei *length,
1861 GLint *params)
1862{
1863 if (!context->getExtensions().disjointTimerQuery)
1864 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001865 context->handleError(InvalidOperation() << "Timer query extension not enabled");
Geoff Lang2186c382016-10-14 10:54:54 -04001866 return false;
1867 }
1868
1869 if (!ValidateRobustEntryPoint(context, bufSize))
1870 {
1871 return false;
1872 }
1873
Brandon Jonesd1049182018-03-28 10:02:20 -07001874 GLsizei numParams = 0;
1875
1876 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001877 {
1878 return false;
1879 }
1880
Brandon Jonesd1049182018-03-28 10:02:20 -07001881 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001882 {
1883 return false;
1884 }
1885
Brandon Jonesd1049182018-03-28 10:02:20 -07001886 SetRobustLengthParam(length, numParams);
1887
Geoff Lang2186c382016-10-14 10:54:54 -04001888 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001889}
1890
1891bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1892{
1893 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001894 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001895 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001896 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001897 return false;
1898 }
Geoff Lang2186c382016-10-14 10:54:54 -04001899 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1900}
1901
1902bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1903 GLuint id,
1904 GLenum pname,
1905 GLsizei bufSize,
1906 GLsizei *length,
1907 GLuint *params)
1908{
1909 if (!context->getExtensions().disjointTimerQuery &&
1910 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1911 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001912 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001913 return false;
1914 }
1915
1916 if (!ValidateRobustEntryPoint(context, bufSize))
1917 {
1918 return false;
1919 }
1920
Brandon Jonesd1049182018-03-28 10:02:20 -07001921 GLsizei numParams = 0;
1922
1923 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001924 {
1925 return false;
1926 }
1927
Brandon Jonesd1049182018-03-28 10:02:20 -07001928 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001929 {
1930 return false;
1931 }
1932
Brandon Jonesd1049182018-03-28 10:02:20 -07001933 SetRobustLengthParam(length, numParams);
1934
Geoff Lang2186c382016-10-14 10:54:54 -04001935 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001936}
1937
1938bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1939{
1940 if (!context->getExtensions().disjointTimerQuery)
1941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001942 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001943 return false;
1944 }
Geoff Lang2186c382016-10-14 10:54:54 -04001945 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1946}
1947
1948bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1949 GLuint id,
1950 GLenum pname,
1951 GLsizei bufSize,
1952 GLsizei *length,
1953 GLint64 *params)
1954{
1955 if (!context->getExtensions().disjointTimerQuery)
1956 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001958 return false;
1959 }
1960
1961 if (!ValidateRobustEntryPoint(context, bufSize))
1962 {
1963 return false;
1964 }
1965
Brandon Jonesd1049182018-03-28 10:02:20 -07001966 GLsizei numParams = 0;
1967
1968 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001969 {
1970 return false;
1971 }
1972
Brandon Jonesd1049182018-03-28 10:02:20 -07001973 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001974 {
1975 return false;
1976 }
1977
Brandon Jonesd1049182018-03-28 10:02:20 -07001978 SetRobustLengthParam(length, numParams);
1979
Geoff Lang2186c382016-10-14 10:54:54 -04001980 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001981}
1982
1983bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
1984{
1985 if (!context->getExtensions().disjointTimerQuery)
1986 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001987 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001988 return false;
1989 }
Geoff Lang2186c382016-10-14 10:54:54 -04001990 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1991}
1992
1993bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
1994 GLuint id,
1995 GLenum pname,
1996 GLsizei bufSize,
1997 GLsizei *length,
1998 GLuint64 *params)
1999{
2000 if (!context->getExtensions().disjointTimerQuery)
2001 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002003 return false;
2004 }
2005
2006 if (!ValidateRobustEntryPoint(context, bufSize))
2007 {
2008 return false;
2009 }
2010
Brandon Jonesd1049182018-03-28 10:02:20 -07002011 GLsizei numParams = 0;
2012
2013 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002014 {
2015 return false;
2016 }
2017
Brandon Jonesd1049182018-03-28 10:02:20 -07002018 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002019 {
2020 return false;
2021 }
2022
Brandon Jonesd1049182018-03-28 10:02:20 -07002023 SetRobustLengthParam(length, numParams);
2024
Geoff Lang2186c382016-10-14 10:54:54 -04002025 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002026}
2027
Jamie Madill5b772312018-03-08 20:28:32 -05002028bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002029 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002030 GLint location,
2031 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002032 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002033{
Jiajia Qin5451d532017-11-16 17:16:34 +08002034 // TODO(Jiajia): Add image uniform check in future.
2035 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002036 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002037 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002038 return false;
2039 }
2040
Jiajia Qin5451d532017-11-16 17:16:34 +08002041 if (!program)
2042 {
2043 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidProgramName);
2044 return false;
2045 }
2046
2047 if (!program->isLinked())
2048 {
2049 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
2050 return false;
2051 }
2052
2053 if (location == -1)
2054 {
2055 // Silently ignore the uniform command
2056 return false;
2057 }
2058
2059 const auto &uniformLocations = program->getUniformLocations();
2060 size_t castedLocation = static_cast<size_t>(location);
2061 if (castedLocation >= uniformLocations.size())
2062 {
2063 context->handleError(InvalidOperation() << "Invalid uniform location");
2064 return false;
2065 }
2066
2067 const auto &uniformLocation = uniformLocations[castedLocation];
2068 if (uniformLocation.ignored)
2069 {
2070 // Silently ignore the uniform command
2071 return false;
2072 }
2073
2074 if (!uniformLocation.used())
2075 {
2076 context->handleError(InvalidOperation());
2077 return false;
2078 }
2079
2080 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2081
2082 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002083 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002084 {
2085 context->handleError(InvalidOperation());
2086 return false;
2087 }
2088
2089 *uniformOut = &uniform;
2090 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002091}
2092
Jamie Madill5b772312018-03-08 20:28:32 -05002093bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002094 GLenum uniformType,
2095 GLsizei count,
2096 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002097{
Jiajia Qin5451d532017-11-16 17:16:34 +08002098 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2099 // It is compatible with INT or BOOL.
2100 // Do these cheap tests first, for a little extra speed.
2101 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002102 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002103 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002104 }
2105
Jiajia Qin5451d532017-11-16 17:16:34 +08002106 if (IsSamplerType(uniformType))
2107 {
2108 // Check that the values are in range.
2109 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2110 for (GLsizei i = 0; i < count; ++i)
2111 {
2112 if (value[i] < 0 || value[i] >= max)
2113 {
2114 context->handleError(InvalidValue() << "sampler uniform value out of range");
2115 return false;
2116 }
2117 }
2118 return true;
2119 }
2120
2121 context->handleError(InvalidOperation() << "wrong type of value for uniform");
2122 return false;
2123}
2124
Jamie Madill5b772312018-03-08 20:28:32 -05002125bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002126{
2127 // Check that the value type is compatible with uniform type.
2128 if (valueType == uniformType)
2129 {
2130 return true;
2131 }
2132
2133 context->handleError(InvalidOperation() << "wrong type of value for uniform");
2134 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002135}
2136
Jamie Madill5b772312018-03-08 20:28:32 -05002137bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002138{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002139 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002140 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002141 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2142 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002143}
2144
Jamie Madill5b772312018-03-08 20:28:32 -05002145bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002146{
2147 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002148 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002149 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2150 ValidateUniform1ivValue(context, uniform->type, count, value);
2151}
2152
Jamie Madill5b772312018-03-08 20:28:32 -05002153bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002154 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002155 GLint location,
2156 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002157 GLboolean transpose)
2158{
Geoff Lang92019432017-11-20 13:09:34 -05002159 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002160 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002161 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002162 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002163 }
2164
Jamie Madill62d31cb2015-09-11 13:25:51 -04002165 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002166 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002167 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2168 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002169}
2170
Jamie Madill5b772312018-03-08 20:28:32 -05002171bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002172{
2173 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04002176 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002177 }
2178
Jamie Madill0af26e12015-03-05 19:54:33 -05002179 const Caps &caps = context->getCaps();
2180
Jamie Madill893ab082014-05-16 16:56:10 -04002181 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2182 {
2183 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2184
Jamie Madill0af26e12015-03-05 19:54:33 -05002185 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002187 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002188 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002189 }
2190 }
2191
2192 switch (pname)
2193 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002194 case GL_TEXTURE_BINDING_2D:
2195 case GL_TEXTURE_BINDING_CUBE_MAP:
2196 case GL_TEXTURE_BINDING_3D:
2197 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002198 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002199 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002200 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002201 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002202 {
2203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
2204 return false;
2205 }
2206 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002207 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2208 if (!context->getExtensions().textureRectangle)
2209 {
2210 context->handleError(InvalidEnum()
2211 << "ANGLE_texture_rectangle extension not present");
2212 return false;
2213 }
2214 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002215 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2216 if (!context->getExtensions().eglStreamConsumerExternal &&
2217 !context->getExtensions().eglImageExternal)
2218 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002219 context->handleError(InvalidEnum() << "Neither NV_EGL_stream_consumer_external "
2220 "nor GL_OES_EGL_image_external "
2221 "extensions enabled");
He Yunchaoced53ae2016-11-29 15:00:51 +08002222 return false;
2223 }
2224 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002225
He Yunchaoced53ae2016-11-29 15:00:51 +08002226 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2227 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002228 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002229 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2230 ASSERT(readFramebuffer);
2231
Jamie Madill427064d2018-04-13 16:20:34 -04002232 if (!ValidateFramebufferComplete<InvalidOperation>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002233 {
Geoff Langb1196682014-07-23 13:47:29 -04002234 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002235 }
2236
Jamie Madille98b1b52018-03-08 09:47:23 -05002237 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002238 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002239 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002240 return false;
2241 }
2242
Jamie Madille98b1b52018-03-08 09:47:23 -05002243 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002244 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002247 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002248 }
2249 }
2250 break;
2251
He Yunchaoced53ae2016-11-29 15:00:51 +08002252 default:
2253 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002254 }
2255
2256 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002257 if (*numParams == 0)
2258 {
2259 return false;
2260 }
2261
2262 return true;
2263}
2264
Brandon Jonesd1049182018-03-28 10:02:20 -07002265bool ValidateGetBooleanvRobustANGLE(Context *context,
2266 GLenum pname,
2267 GLsizei bufSize,
2268 GLsizei *length,
2269 GLboolean *params)
2270{
2271 GLenum nativeType;
2272 unsigned int numParams = 0;
2273
2274 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2275 {
2276 return false;
2277 }
2278
2279 SetRobustLengthParam(length, numParams);
2280
2281 return true;
2282}
2283
2284bool ValidateGetFloatvRobustANGLE(Context *context,
2285 GLenum pname,
2286 GLsizei bufSize,
2287 GLsizei *length,
2288 GLfloat *params)
2289{
2290 GLenum nativeType;
2291 unsigned int numParams = 0;
2292
2293 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2294 {
2295 return false;
2296 }
2297
2298 SetRobustLengthParam(length, numParams);
2299
2300 return true;
2301}
2302
2303bool ValidateGetIntegervRobustANGLE(Context *context,
2304 GLenum pname,
2305 GLsizei bufSize,
2306 GLsizei *length,
2307 GLint *data)
2308{
2309 GLenum nativeType;
2310 unsigned int numParams = 0;
2311
2312 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2313 {
2314 return false;
2315 }
2316
2317 SetRobustLengthParam(length, numParams);
2318
2319 return true;
2320}
2321
2322bool ValidateGetInteger64vRobustANGLE(Context *context,
2323 GLenum pname,
2324 GLsizei bufSize,
2325 GLsizei *length,
2326 GLint64 *data)
2327{
2328 GLenum nativeType;
2329 unsigned int numParams = 0;
2330
2331 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2332 {
2333 return false;
2334 }
2335
2336 if (nativeType == GL_INT_64_ANGLEX)
2337 {
2338 CastStateValues(context, nativeType, pname, numParams, data);
2339 return false;
2340 }
2341
2342 SetRobustLengthParam(length, numParams);
2343 return true;
2344}
2345
Jamie Madill5b772312018-03-08 20:28:32 -05002346bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002347 GLenum pname,
2348 GLsizei bufSize,
2349 GLenum *nativeType,
2350 unsigned int *numParams)
2351{
2352 if (!ValidateRobustEntryPoint(context, bufSize))
2353 {
2354 return false;
2355 }
2356
2357 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2358 {
2359 return false;
2360 }
2361
2362 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002363 {
2364 return false;
2365 }
2366
2367 return true;
2368}
2369
Jamie Madill5b772312018-03-08 20:28:32 -05002370bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002371 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002372 GLint level,
2373 GLenum internalformat,
2374 bool isSubImage,
2375 GLint xoffset,
2376 GLint yoffset,
2377 GLint zoffset,
2378 GLint x,
2379 GLint y,
2380 GLsizei width,
2381 GLsizei height,
2382 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002383 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002384{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002385 TextureType texType = TextureTargetToType(target);
2386
Brandon Jones6cad5662017-06-14 13:25:13 -07002387 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002388 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002389 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
2390 return false;
2391 }
2392
2393 if (width < 0 || height < 0)
2394 {
2395 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002396 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002397 }
2398
He Yunchaoced53ae2016-11-29 15:00:51 +08002399 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2400 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002401 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002402 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002403 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002404 }
2405
2406 if (border != 0)
2407 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002408 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002409 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002410 }
2411
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002412 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002413 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002414 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002415 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002416 }
2417
Jamie Madill43da7c42018-08-01 11:34:49 -04002418 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002419 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002420 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002421 {
Geoff Langb1196682014-07-23 13:47:29 -04002422 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002423 }
2424
Jamie Madille98b1b52018-03-08 09:47:23 -05002425 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002426 {
Geoff Langb1196682014-07-23 13:47:29 -04002427 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002428 }
2429
Martin Radev138064f2016-07-15 12:03:41 +03002430 if (readFramebuffer->getReadBufferState() == GL_NONE)
2431 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002433 return false;
2434 }
2435
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002436 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2437 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002438 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002439 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002440 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2441 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002444 return false;
2445 }
2446
Martin Radev04e2c3b2017-07-27 16:54:35 +03002447 // ANGLE_multiview spec, Revision 1:
2448 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2449 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002450 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2451 // framebuffer is more than one.
2452 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002453 {
2454 context->handleError(InvalidFramebufferOperation()
2455 << "The active read framebuffer object has multiview attachments.");
2456 return false;
2457 }
2458
Jamie Madill43da7c42018-08-01 11:34:49 -04002459 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002460
Geoff Langaae65a42014-05-26 12:43:44 -04002461 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002462 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002463 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002464 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002465 maxDimension = caps.max2DTextureSize;
2466 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002467
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002468 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002469 maxDimension = caps.maxCubeMapTextureSize;
2470 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002471
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002472 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002473 maxDimension = caps.maxRectangleTextureSize;
2474 break;
2475
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002476 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002477 maxDimension = caps.max2DTextureSize;
2478 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002479
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002480 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002481 maxDimension = caps.max3DTextureSize;
2482 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002483
He Yunchaoced53ae2016-11-29 15:00:51 +08002484 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002485 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08002486 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002487 }
2488
Jamie Madill43da7c42018-08-01 11:34:49 -04002489 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002490 if (!texture)
2491 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002492 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002493 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002494 }
2495
Geoff Lang69cce582015-09-17 13:20:36 -04002496 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002497 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002498 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002499 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002500 }
2501
Jamie Madill43da7c42018-08-01 11:34:49 -04002502 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002503 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002504 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002505
Geoff Lang966c9402017-04-18 12:38:27 -04002506 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002508 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05002509 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002510 }
2511
2512 if (isSubImage)
2513 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002514 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2515 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2516 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002517 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002518 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002519 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002520 }
2521 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002522 else
2523 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002524 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002526 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002527 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002528 }
2529
Geoff Langeb66a6e2016-10-31 13:06:12 -04002530 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002531 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002532 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002533 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002534 }
2535
2536 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002537 if (static_cast<int>(width) > maxLevelDimension ||
2538 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002539 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002540 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002541 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002542 }
2543 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002544
Jamie Madill0c8abca2016-07-22 20:21:26 -04002545 if (textureFormatOut)
2546 {
2547 *textureFormatOut = texture->getFormat(target, level);
2548 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002549
2550 // Detect texture copying feedback loops for WebGL.
2551 if (context->getExtensions().webglCompatibility)
2552 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002553 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002554 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002556 return false;
2557 }
2558 }
2559
Jamie Madill560a8d82014-05-21 13:06:20 -04002560 return true;
2561}
2562
Jamie Madillb42162f2018-08-20 12:58:37 -04002563// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2564// completeness check.
2565const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002566{
2567 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002568 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002569
2570 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2571 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2572 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002573 VertexArray *vertexArray = state.getVertexArray();
2574 ASSERT(vertexArray);
2575
2576 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002577 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002578 return kErrorBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002579 }
2580
2581 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2582 // Section 6.10 of the WebGL 1.0 spec.
2583 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002584 ASSERT(framebuffer);
2585
Jamie Madille7d80f32018-08-08 15:49:23 -04002586 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2587 {
2588 ASSERT(framebuffer);
2589 const FramebufferAttachment *dsAttachment =
2590 framebuffer->getStencilOrDepthStencilAttachment();
2591 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2592 ASSERT(stencilBits <= 8);
2593
2594 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2595 if (depthStencilState.stencilTest && stencilBits > 0)
2596 {
2597 GLuint maxStencilValue = (1 << stencilBits) - 1;
2598
2599 bool differentRefs =
2600 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2601 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2602 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2603 (depthStencilState.stencilBackWritemask & maxStencilValue);
2604 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2605 (depthStencilState.stencilBackMask & maxStencilValue);
2606
2607 if (differentRefs || differentWritemasks || differentMasks)
2608 {
2609 if (!extensions.webglCompatibility)
2610 {
2611 WARN() << "This ANGLE implementation does not support separate front/back "
2612 "stencil writemasks, reference values, or stencil mask values.";
2613 }
Jamie Madillb42162f2018-08-20 12:58:37 -04002614 return kErrorStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002615 }
2616 }
2617 }
2618
2619 if (!framebuffer->isComplete(context))
2620 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002621 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
2622 return kErrorDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002623 }
2624
2625 if (context->getStateCache().hasAnyEnabledClientAttrib())
2626 {
2627 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2628 {
2629 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2630 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2631 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2632 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madillb42162f2018-08-20 12:58:37 -04002633 return kErrorVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002634 }
2635
2636 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2637 {
2638 // This is an application error that would normally result in a crash, but we catch it
2639 // and return an error
Jamie Madillb42162f2018-08-20 12:58:37 -04002640 return kErrorVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002641 }
2642 }
2643
2644 // If we are running GLES1, there is no current program.
2645 if (context->getClientVersion() >= Version(2, 0))
2646 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002647 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002648 if (!program)
2649 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002650 return kErrorProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002651 }
2652
2653 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2654 // vertex shader stage or fragment shader stage is a undefined behaviour.
2655 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2656 // produce undefined result.
2657 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2658 !program->hasLinkedShaderStage(ShaderType::Fragment))
2659 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002660 return kErrorNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002661 }
2662
2663 if (!program->validateSamplers(nullptr, context->getCaps()))
2664 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002665 return kErrorTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002666 }
2667
2668 if (extensions.multiview)
2669 {
2670 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2671 const int framebufferNumViews = framebuffer->getNumViews();
2672 if (framebufferNumViews != programNumViews)
2673 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002674 return kErrorMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002675 }
2676
2677 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2678 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2679 framebufferNumViews > 1)
2680 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002681 return kErrorMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002682 }
2683
2684 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2685 state.isQueryActive(QueryType::TimeElapsed))
2686 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002687 return kErrorMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002688 }
2689 }
2690
2691 // Uniform buffer validation
2692 for (unsigned int uniformBlockIndex = 0;
2693 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2694 {
2695 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002696 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002697 const OffsetBindingPointer<Buffer> &uniformBuffer =
2698 state.getIndexedUniformBuffer(blockBinding);
2699
2700 if (uniformBuffer.get() == nullptr)
2701 {
2702 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002703 return kErrorUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002704 }
2705
2706 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2707 if (uniformBufferSize < uniformBlock.dataSize)
2708 {
2709 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002710 return kErrorUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002711 }
2712
2713 if (extensions.webglCompatibility &&
2714 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2715 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002716 return kErrorUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002717 }
2718 }
2719
2720 // Do some additonal WebGL-specific validation
2721 if (extensions.webglCompatibility)
2722 {
2723 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2724 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2725 transformFeedbackObject->buffersBoundForOtherUse())
2726 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002727 return kErrorTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002728 }
2729
2730 // Detect rendering feedback loops for WebGL.
2731 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2732 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002733 return kErrorFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002734 }
2735
2736 // Detect that the vertex shader input types match the attribute types
2737 if (!ValidateVertexShaderAttributeTypeMatch(context))
2738 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002739 return kErrorVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002740 }
2741
2742 // Detect that the color buffer types match the fragment shader output types
2743 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2744 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002745 return kErrorDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002746 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002747
2748 const VertexArray *vao = context->getGLState().getVertexArray();
2749 if (vao->hasTransformFeedbackBindingConflict(context))
2750 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002751 return kErrorVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002752 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002753 }
2754 }
2755
Jamie Madillb42162f2018-08-20 12:58:37 -04002756 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002757}
2758
Jamie Madill16e28fd2018-09-12 11:03:05 -04002759bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002760{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002761 const Extensions &extensions = context->getExtensions();
2762
Jamie Madill1aeb1312014-06-20 13:21:25 -04002763 switch (mode)
2764 {
Jamie Madill493f9572018-05-24 19:52:15 -04002765 case PrimitiveMode::Points:
2766 case PrimitiveMode::Lines:
2767 case PrimitiveMode::LineLoop:
2768 case PrimitiveMode::LineStrip:
2769 case PrimitiveMode::Triangles:
2770 case PrimitiveMode::TriangleStrip:
2771 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002772 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002773
Jamie Madill493f9572018-05-24 19:52:15 -04002774 case PrimitiveMode::LinesAdjacency:
2775 case PrimitiveMode::LineStripAdjacency:
2776 case PrimitiveMode::TrianglesAdjacency:
2777 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002778 if (!extensions.geometryShader)
2779 {
2780 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
2781 return false;
2782 }
2783 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002784 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002785 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002786 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002787 }
2788
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002789 // If we are running GLES1, there is no current program.
2790 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002791 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002792 const State &state = context->getGLState();
2793
Jamie Madill785e8a02018-10-04 17:42:00 -04002794 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002795 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002796
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002797 // Do geometry shader specific validations
2798 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002799 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002800 if (!IsCompatibleDrawModeWithGeometryShader(
2801 mode, program->getGeometryShaderInputPrimitiveType()))
2802 {
2803 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2804 IncompatibleDrawModeAgainstGeometryShader);
2805 return false;
2806 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002807 }
2808 }
2809
Jamie Madill9fdaa492018-02-16 10:52:11 -05002810 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002811}
2812
Jamie Madill16e28fd2018-09-12 11:03:05 -04002813bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
2814{
2815 if (!context->getStateCache().isValidDrawMode(mode))
2816 {
2817 return ValidateDrawMode(context, mode);
2818 }
2819
2820 if (count < 0)
2821 {
2822 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
2823 return false;
2824 }
2825
2826 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2827 if (drawStatesError)
2828 {
2829 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2830
2831 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2832 // Incomplete.
2833 GLenum errorCode =
2834 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2835 : GL_INVALID_OPERATION);
2836 context->handleError(Error(errorCode, errorMessage));
2837 return false;
2838 }
2839
2840 return true;
2841}
2842
Jamie Madill5b772312018-03-08 20:28:32 -05002843bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002844 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002845 GLint first,
2846 GLsizei count,
2847 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002848{
Jamie Madillfd716582014-06-06 17:09:04 -04002849 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002850 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002851 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002852 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002853 }
2854
Jamie Madill16e28fd2018-09-12 11:03:05 -04002855 if (count < 0)
2856 {
2857 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
2858 return false;
2859 }
2860
Jamie Madill7f232932018-09-12 11:03:06 -04002861 const State &state = context->getGLState();
2862 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002863 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002864 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002865 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002866 if (!ValidateTransformFeedbackPrimitiveMode(context,
2867 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002868 {
James Darpinian30b604d2018-03-12 17:26:57 -07002869 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
2870 return false;
2871 }
2872
2873 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2874 {
2875 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TransformFeedbackBufferTooSmall);
2876 return false;
2877 }
Jamie Madillfd716582014-06-06 17:09:04 -04002878 }
2879
Jamie Madill16e28fd2018-09-12 11:03:05 -04002880 if (!context->getStateCache().isValidDrawMode(mode))
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002881 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002882 return ValidateDrawMode(context, mode);
2883 }
2884
2885 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2886 if (drawStatesError)
2887 {
2888 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2889
2890 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2891 // Incomplete.
2892 GLenum errorCode =
2893 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2894 : GL_INVALID_OPERATION);
2895 context->handleError(Error(errorCode, errorMessage));
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002896 return false;
2897 }
2898
Corentin Wallez71168a02016-12-19 15:11:18 -08002899 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002900 // - first < 0 has been checked as an error condition.
2901 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002902 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002903 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002904 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002905 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002906 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2907 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2908 {
2909 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
2910 return false;
2911 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002912
Jamie Madill2da53562018-08-01 11:34:47 -04002913 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002914 {
2915 return false;
2916 }
Jamie Madillfd716582014-06-06 17:09:04 -04002917 }
2918
2919 return true;
2920}
2921
He Yunchaoced53ae2016-11-29 15:00:51 +08002922bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002923 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002924 GLint first,
2925 GLsizei count,
2926 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002927{
Geoff Lang63c5a592017-09-27 14:08:16 -04002928 if (!context->getExtensions().instancedArrays)
2929 {
2930 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
2931 return false;
2932 }
2933
Corentin Wallez170efbf2017-05-02 13:45:01 -04002934 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002935 {
2936 return false;
2937 }
2938
Corentin Wallez0dc97812017-06-22 14:38:44 -04002939 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002940}
2941
Jamie Madill493f9572018-05-24 19:52:15 -04002942bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, GLenum type)
Jamie Madillfd716582014-06-06 17:09:04 -04002943{
Jamie Madill250d33f2014-06-06 17:09:03 -04002944 switch (type)
2945 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002946 case GL_UNSIGNED_BYTE:
2947 case GL_UNSIGNED_SHORT:
2948 break;
2949 case GL_UNSIGNED_INT:
2950 if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
2951 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002952 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002953 return false;
2954 }
2955 break;
2956 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002957 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002958 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002959 }
2960
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002961 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002962
Jamie Madill43da7c42018-08-01 11:34:49 -04002963 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002964 if (curTransformFeedback && curTransformFeedback->isActive() &&
2965 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002966 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002967 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2968 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2969 if (context->getExtensions().geometryShader)
2970 {
2971 if (!ValidateTransformFeedbackPrimitiveMode(
2972 context, curTransformFeedback->getPrimitiveMode(), mode))
2973 {
2974 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
2975 return false;
2976 }
2977 }
2978 else
2979 {
2980 // It is an invalid operation to call DrawElements, DrawRangeElements or
2981 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
2982 // 86)
2983 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2984 UnsupportedDrawModeForTransformFeedback);
2985 return false;
2986 }
Jamie Madill250d33f2014-06-06 17:09:03 -04002987 }
2988
Jiajia Qind9671222016-11-29 16:30:31 +08002989 return true;
2990}
2991
Jamie Madill5b772312018-03-08 20:28:32 -05002992bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002993 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002994 GLsizei count,
2995 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002996 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002997 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08002998{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002999 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003000 return false;
3001
3002 const State &state = context->getGLState();
3003
Corentin Wallez170efbf2017-05-02 13:45:01 -04003004 if (!ValidateDrawBase(context, mode, count))
3005 {
3006 return false;
3007 }
3008
Jamie Madill43da7c42018-08-01 11:34:49 -04003009 const VertexArray *vao = state.getVertexArray();
3010 Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003011
Jamie Madill43da7c42018-08-01 11:34:49 -04003012 GLuint typeBytes = GetTypeInfo(type).bytes;
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003013
3014 if (context->getExtensions().webglCompatibility)
3015 {
3016 ASSERT(isPow2(typeBytes) && typeBytes > 0);
3017 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3018 {
3019 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3020 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3021 // data type passed to the call, or an INVALID_OPERATION error is generated.
Brandon Jones6cad5662017-06-14 13:25:13 -07003022 ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003023 return false;
3024 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003025
3026 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3027 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3028 // error is generated.
3029 if (reinterpret_cast<intptr_t>(indices) < 0)
3030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003031 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003032 return false;
3033 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003034 }
Jamie Madillcc73f242018-08-01 11:34:48 -04003035 else if (elementArrayBuffer && elementArrayBuffer->isMapped())
3036 {
3037 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3038 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the WebGL 2.0 API.
3039 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
3040 context->handleError(InvalidOperation() << "Index buffer is mapped.");
3041 return false;
3042 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003043
3044 if (context->getExtensions().webglCompatibility ||
3045 !context->getGLState().areClientArraysEnabled())
3046 {
Brandon Jones2a018152018-06-08 15:59:26 -07003047 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003048 {
3049 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003050 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3051 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Brandon Jones6cad5662017-06-14 13:25:13 -07003052 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003053 return false;
3054 }
3055 }
3056
Jamie Madill9fdaa492018-02-16 10:52:11 -05003057 if (count > 0 && !elementArrayBuffer && !indices)
Jamie Madillae3000b2014-08-25 15:47:51 -04003058 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003059 // This is an application error that would normally result in a crash, but we catch it and
3060 // return an error
3061 context->handleError(InvalidOperation() << "No element array buffer and no pointer.");
3062 return false;
3063 }
3064
3065 if (count > 0 && elementArrayBuffer)
3066 {
3067 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3068 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3069 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3070 constexpr uint64_t kMaxTypeSize = 8;
3071 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3072 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3073 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3074
3075 uint64_t typeSize = typeBytes;
3076 uint64_t elementCount = static_cast<uint64_t>(count);
3077 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3078
3079 // Doing the multiplication here is overflow-safe
3080 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3081
3082 // The offset can be any value, check for overflows
3083 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3084 if (elementDataSizeNoOffset > kUint64Max - offset)
Jamie Madillae3000b2014-08-25 15:47:51 -04003085 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003086 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
3087 return false;
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003088 }
Jamie Madill9fdaa492018-02-16 10:52:11 -05003089
3090 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3091 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003092 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003093 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
3094 return false;
3095 }
3096
3097 ASSERT(isPow2(typeSize) && typeSize > 0);
3098 if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0)
3099 {
3100 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedByteCountType);
Geoff Langb1196682014-07-23 13:47:29 -04003101 return false;
Jamie Madillae3000b2014-08-25 15:47:51 -04003102 }
James Darpiniane8a93c62018-01-04 18:02:24 -08003103
3104 if (context->getExtensions().webglCompatibility &&
3105 elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
3106 {
3107 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
3108 ElementArrayBufferBoundForTransformFeedback);
3109 return false;
3110 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003111 }
3112
Jamie Madill2da53562018-08-01 11:34:47 -04003113 if (!context->getExtensions().robustBufferAccessBehavior && count > 0 && primcount > 0)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003114 {
3115 // Use the parameter buffer to retrieve and cache the index range.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003116 const DrawCallParams &params = context->getParams<DrawCallParams>();
3117 ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
3118 const IndexRange &indexRange = params.getIndexRange();
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003119
3120 // If we use an index greater than our maximum supported index range, return an error.
3121 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
3122 // return an error if possible here.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003123 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003124 {
3125 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement);
3126 return false;
3127 }
3128
Jamie Madill2da53562018-08-01 11:34:47 -04003129 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003130 {
3131 return false;
3132 }
3133
3134 // No op if there are no real indices in the index data (all are primitive restart).
Jamie Madill6f5444d2018-03-14 10:08:11 -04003135 return (indexRange.vertexIndexCount > 0);
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003136 }
3137
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003138 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003139}
3140
Jamie Madill5b772312018-03-08 20:28:32 -05003141bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003142 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003143 GLsizei count,
3144 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003145 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003146 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003147{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003148 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003149}
3150
Geoff Lang3edfe032015-09-04 16:38:24 -04003151bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003152 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003153 GLsizei count,
3154 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003155 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003156 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003157{
Geoff Lang63c5a592017-09-27 14:08:16 -04003158 if (!context->getExtensions().instancedArrays)
3159 {
3160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3161 return false;
3162 }
3163
Corentin Wallez170efbf2017-05-02 13:45:01 -04003164 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003165 {
3166 return false;
3167 }
3168
Corentin Wallez0dc97812017-06-22 14:38:44 -04003169 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003170}
3171
He Yunchaoced53ae2016-11-29 15:00:51 +08003172bool ValidateFramebufferTextureBase(Context *context,
3173 GLenum target,
3174 GLenum attachment,
3175 GLuint texture,
3176 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003177{
Geoff Lange8afa902017-09-27 15:00:43 -04003178 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003179 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003180 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003181 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003182 }
3183
3184 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003185 {
3186 return false;
3187 }
3188
Jamie Madill55ec3b12014-07-03 10:38:57 -04003189 if (texture != 0)
3190 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003191 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003192
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003193 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003195 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04003196 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003197 }
3198
3199 if (level < 0)
3200 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003201 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04003202 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003203 }
3204 }
3205
Jamie Madill43da7c42018-08-01 11:34:49 -04003206 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003207 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003208
Jamie Madill84115c92015-04-23 15:00:07 -04003209 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003211 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003212 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003213 }
3214
3215 return true;
3216}
3217
Geoff Langb1196682014-07-23 13:47:29 -04003218bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003219{
3220 if (program == 0)
3221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003222 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04003223 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003224 }
3225
Jamie Madill43da7c42018-08-01 11:34:49 -04003226 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003227 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003228 {
3229 return false;
3230 }
3231
Jamie Madill0063c512014-08-25 15:47:53 -04003232 if (!programObject || !programObject->isLinked())
3233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003234 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003235 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003236 }
3237
Geoff Lang7dd2e102014-11-10 15:19:26 -05003238 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003240 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04003241 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003242 }
3243
Jamie Madill0063c512014-08-25 15:47:53 -04003244 return true;
3245}
3246
Geoff Langf41d0ee2016-10-07 13:04:23 -04003247static bool ValidateSizedGetUniform(Context *context,
3248 GLuint program,
3249 GLint location,
3250 GLsizei bufSize,
3251 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003252{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003253 if (length)
3254 {
3255 *length = 0;
3256 }
3257
Jamie Madill78f41802014-08-25 15:47:55 -04003258 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003259 {
Jamie Madill78f41802014-08-25 15:47:55 -04003260 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003261 }
3262
Geoff Langf41d0ee2016-10-07 13:04:23 -04003263 if (bufSize < 0)
3264 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003265 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003266 return false;
3267 }
3268
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003269 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003270 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003271
Jamie Madill78f41802014-08-25 15:47:55 -04003272 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003273 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003274 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003275 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003276 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003277 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003278 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003279 }
3280
Geoff Langf41d0ee2016-10-07 13:04:23 -04003281 if (length)
3282 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003283 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003284 }
3285
Jamie Madill0063c512014-08-25 15:47:53 -04003286 return true;
3287}
3288
He Yunchaoced53ae2016-11-29 15:00:51 +08003289bool ValidateGetnUniformfvEXT(Context *context,
3290 GLuint program,
3291 GLint location,
3292 GLsizei bufSize,
3293 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003294{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003295 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003296}
3297
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003298bool ValidateGetnUniformfvRobustANGLE(Context *context,
3299 GLuint program,
3300 GLint location,
3301 GLsizei bufSize,
3302 GLsizei *length,
3303 GLfloat *params)
3304{
3305 UNIMPLEMENTED();
3306 return false;
3307}
3308
He Yunchaoced53ae2016-11-29 15:00:51 +08003309bool ValidateGetnUniformivEXT(Context *context,
3310 GLuint program,
3311 GLint location,
3312 GLsizei bufSize,
3313 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003314{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003315 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3316}
3317
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003318bool ValidateGetnUniformivRobustANGLE(Context *context,
3319 GLuint program,
3320 GLint location,
3321 GLsizei bufSize,
3322 GLsizei *length,
3323 GLint *params)
3324{
3325 UNIMPLEMENTED();
3326 return false;
3327}
3328
3329bool ValidateGetnUniformuivRobustANGLE(Context *context,
3330 GLuint program,
3331 GLint location,
3332 GLsizei bufSize,
3333 GLsizei *length,
3334 GLuint *params)
3335{
3336 UNIMPLEMENTED();
3337 return false;
3338}
3339
Geoff Langf41d0ee2016-10-07 13:04:23 -04003340bool ValidateGetUniformfvRobustANGLE(Context *context,
3341 GLuint program,
3342 GLint location,
3343 GLsizei bufSize,
3344 GLsizei *length,
3345 GLfloat *params)
3346{
3347 if (!ValidateRobustEntryPoint(context, bufSize))
3348 {
3349 return false;
3350 }
3351
Brandon Jonesd1049182018-03-28 10:02:20 -07003352 GLsizei writeLength = 0;
3353
Geoff Langf41d0ee2016-10-07 13:04:23 -04003354 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003355 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3356 {
3357 return false;
3358 }
3359
3360 SetRobustLengthParam(length, writeLength);
3361
3362 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003363}
3364
3365bool ValidateGetUniformivRobustANGLE(Context *context,
3366 GLuint program,
3367 GLint location,
3368 GLsizei bufSize,
3369 GLsizei *length,
3370 GLint *params)
3371{
3372 if (!ValidateRobustEntryPoint(context, bufSize))
3373 {
3374 return false;
3375 }
3376
Brandon Jonesd1049182018-03-28 10:02:20 -07003377 GLsizei writeLength = 0;
3378
Geoff Langf41d0ee2016-10-07 13:04:23 -04003379 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003380 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3381 {
3382 return false;
3383 }
3384
3385 SetRobustLengthParam(length, writeLength);
3386
3387 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003388}
3389
3390bool ValidateGetUniformuivRobustANGLE(Context *context,
3391 GLuint program,
3392 GLint location,
3393 GLsizei bufSize,
3394 GLsizei *length,
3395 GLuint *params)
3396{
3397 if (!ValidateRobustEntryPoint(context, bufSize))
3398 {
3399 return false;
3400 }
3401
3402 if (context->getClientMajorVersion() < 3)
3403 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08003404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003405 return false;
3406 }
3407
Brandon Jonesd1049182018-03-28 10:02:20 -07003408 GLsizei writeLength = 0;
3409
Geoff Langf41d0ee2016-10-07 13:04:23 -04003410 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003411 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3412 {
3413 return false;
3414 }
3415
3416 SetRobustLengthParam(length, writeLength);
3417
3418 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003419}
3420
He Yunchaoced53ae2016-11-29 15:00:51 +08003421bool ValidateDiscardFramebufferBase(Context *context,
3422 GLenum target,
3423 GLsizei numAttachments,
3424 const GLenum *attachments,
3425 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003426{
3427 if (numAttachments < 0)
3428 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003429 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003430 return false;
3431 }
3432
3433 for (GLsizei i = 0; i < numAttachments; ++i)
3434 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003435 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003436 {
3437 if (defaultFramebuffer)
3438 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003439 ANGLE_VALIDATION_ERR(context, InvalidEnum(), DefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003440 return false;
3441 }
3442
3443 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3444 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003445 context->handleError(InvalidOperation() << "Requested color attachment is "
3446 "greater than the maximum supported "
3447 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003448 return false;
3449 }
3450 }
3451 else
3452 {
3453 switch (attachments[i])
3454 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003455 case GL_DEPTH_ATTACHMENT:
3456 case GL_STENCIL_ATTACHMENT:
3457 case GL_DEPTH_STENCIL_ATTACHMENT:
3458 if (defaultFramebuffer)
3459 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003460 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
3461 DefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003462 return false;
3463 }
3464 break;
3465 case GL_COLOR:
3466 case GL_DEPTH:
3467 case GL_STENCIL:
3468 if (!defaultFramebuffer)
3469 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003470 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
3471 DefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003472 return false;
3473 }
3474 break;
3475 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003476 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003477 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003478 }
3479 }
3480 }
3481
3482 return true;
3483}
3484
Austin Kinross6ee1e782015-05-29 17:05:37 -07003485bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3486{
Jamie Madill007530e2017-12-28 14:27:04 -05003487 if (!context->getExtensions().debugMarker)
3488 {
3489 // The debug marker calls should not set error state
3490 // However, it seems reasonable to set an error state if the extension is not enabled
3491 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3492 return false;
3493 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003494
Jamie Madill007530e2017-12-28 14:27:04 -05003495 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003496 if (length < 0)
3497 {
3498 return false;
3499 }
3500
3501 if (marker == nullptr)
3502 {
3503 return false;
3504 }
3505
3506 return true;
3507}
3508
3509bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3510{
Jamie Madill007530e2017-12-28 14:27:04 -05003511 if (!context->getExtensions().debugMarker)
3512 {
3513 // The debug marker calls should not set error state
3514 // However, it seems reasonable to set an error state if the extension is not enabled
3515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3516 return false;
3517 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003518
Jamie Madill007530e2017-12-28 14:27:04 -05003519 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003520 if (length < 0)
3521 {
3522 return false;
3523 }
3524
3525 if (length > 0 && marker == nullptr)
3526 {
3527 return false;
3528 }
3529
3530 return true;
3531}
3532
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003533bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003534{
Geoff Langa8406172015-07-21 16:53:39 -04003535 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003537 context->handleError(InvalidOperation());
Geoff Langa8406172015-07-21 16:53:39 -04003538 return false;
3539 }
3540
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003541 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003542 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003543 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003544 if (!context->getExtensions().eglImage)
3545 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003546 context->handleError(InvalidEnum()
3547 << "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003548 }
3549 break;
3550
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003551 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003552 if (!context->getExtensions().eglImageExternal)
3553 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003554 context->handleError(InvalidEnum() << "GL_TEXTURE_EXTERNAL_OES texture target "
3555 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003556 }
Geoff Langa8406172015-07-21 16:53:39 -04003557 break;
3558
3559 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003560 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003561 return false;
3562 }
3563
Rafael Cintron05a449a2018-06-20 18:08:04 -07003564 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003565
Jamie Madill61e16b42017-06-19 11:13:23 -04003566 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003567 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003568 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003569 context->handleError(InvalidValue() << "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003570 return false;
3571 }
3572
Jamie Madill007530e2017-12-28 14:27:04 -05003573 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003574 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003575 context->handleError(InvalidOperation()
3576 << "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003577 return false;
3578 }
3579
Yuly Novikov2eb54072018-08-22 16:41:26 -04003580 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003582 context->handleError(InvalidOperation()
3583 << "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003584 return false;
3585 }
3586
Geoff Langdcab33b2015-07-21 13:03:16 -04003587 return true;
3588}
3589
3590bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003591 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003592 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003593{
Geoff Langa8406172015-07-21 16:53:39 -04003594 if (!context->getExtensions().eglImage)
3595 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003596 context->handleError(InvalidOperation());
Geoff Langa8406172015-07-21 16:53:39 -04003597 return false;
3598 }
3599
3600 switch (target)
3601 {
3602 case GL_RENDERBUFFER:
3603 break;
3604
3605 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003606 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003607 return false;
3608 }
3609
Rafael Cintron05a449a2018-06-20 18:08:04 -07003610 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003611
Jamie Madill61e16b42017-06-19 11:13:23 -04003612 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003613 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003615 context->handleError(InvalidValue() << "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003616 return false;
3617 }
3618
Yuly Novikov2eb54072018-08-22 16:41:26 -04003619 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003621 context->handleError(InvalidOperation()
3622 << "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003623 return false;
3624 }
3625
Geoff Langdcab33b2015-07-21 13:03:16 -04003626 return true;
3627}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003628
3629bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3630{
Geoff Lang36167ab2015-12-07 10:27:14 -05003631 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003632 {
3633 // The default VAO should always exist
3634 ASSERT(array != 0);
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003635 context->handleError(InvalidOperation());
Austin Kinrossbc781f32015-10-26 09:27:38 -07003636 return false;
3637 }
3638
3639 return true;
3640}
3641
Geoff Langc5629752015-12-07 16:29:04 -05003642bool ValidateProgramBinaryBase(Context *context,
3643 GLuint program,
3644 GLenum binaryFormat,
3645 const void *binary,
3646 GLint length)
3647{
3648 Program *programObject = GetValidProgram(context, program);
3649 if (programObject == nullptr)
3650 {
3651 return false;
3652 }
3653
3654 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3655 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3656 programBinaryFormats.end())
3657 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003658 context->handleError(InvalidEnum() << "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003659 return false;
3660 }
3661
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003662 if (context->hasActiveTransformFeedback(program))
3663 {
3664 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003665 context->handleError(InvalidOperation() << "Cannot change program binary while program "
3666 "is associated with an active transform "
3667 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003668 return false;
3669 }
3670
Geoff Langc5629752015-12-07 16:29:04 -05003671 return true;
3672}
3673
3674bool ValidateGetProgramBinaryBase(Context *context,
3675 GLuint program,
3676 GLsizei bufSize,
3677 GLsizei *length,
3678 GLenum *binaryFormat,
3679 void *binary)
3680{
3681 Program *programObject = GetValidProgram(context, program);
3682 if (programObject == nullptr)
3683 {
3684 return false;
3685 }
3686
3687 if (!programObject->isLinked())
3688 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003689 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003690 return false;
3691 }
3692
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003693 if (context->getCaps().programBinaryFormats.empty())
3694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003695 context->handleError(InvalidOperation() << "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003696 return false;
3697 }
3698
Geoff Langc5629752015-12-07 16:29:04 -05003699 return true;
3700}
Jamie Madillc29968b2016-01-20 11:17:23 -05003701
Jamie Madill5b772312018-03-08 20:28:32 -05003702bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003703{
3704 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003705 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003706 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003707 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
3708 return false;
3709 }
3710 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3711 {
3712 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003713 return false;
3714 }
3715
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003716 ASSERT(context->getGLState().getDrawFramebuffer());
3717 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003718 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3719
3720 // This should come first before the check for the default frame buffer
3721 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3722 // rather than INVALID_OPERATION
3723 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3724 {
3725 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3726
3727 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003728 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3729 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003730 {
3731 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003732 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3733 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3734 // 3.1 is still a bit ambiguous about the error, but future specs are
3735 // expected to clarify that GL_INVALID_ENUM is the correct error.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003736 context->handleError(InvalidEnum() << "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003737 return false;
3738 }
3739 else if (bufs[colorAttachment] >= maxColorAttachment)
3740 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003741 context->handleError(InvalidOperation()
3742 << "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003743 return false;
3744 }
3745 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3746 frameBufferId != 0)
3747 {
3748 // INVALID_OPERATION-GL is bound to buffer and ith argument
3749 // is not COLOR_ATTACHMENTi or NONE
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003750 context->handleError(InvalidOperation()
3751 << "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003752 return false;
3753 }
3754 }
3755
3756 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3757 // and n is not 1 or bufs is bound to value other than BACK and NONE
3758 if (frameBufferId == 0)
3759 {
3760 if (n != 1)
3761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003762 context->handleError(InvalidOperation()
3763 << "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003764 return false;
3765 }
3766
3767 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3768 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003769 context->handleError(
3770 InvalidOperation()
3771 << "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003772 return false;
3773 }
3774 }
3775
3776 return true;
3777}
3778
Geoff Lang496c02d2016-10-20 11:38:11 -07003779bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003780 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003781 GLenum pname,
3782 GLsizei *length,
3783 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003784{
Geoff Lang496c02d2016-10-20 11:38:11 -07003785 if (length)
3786 {
3787 *length = 0;
3788 }
3789
3790 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3791 {
3792 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003793 InvalidOperation()
3794 << "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003795 return false;
3796 }
3797
Corentin Walleze4477002017-12-01 14:39:58 -05003798 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003799 {
Corentin Wallez336129f2017-10-17 15:55:40 -04003800 context->handleError(InvalidEnum() << "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003801 return false;
3802 }
3803
Geoff Lang496c02d2016-10-20 11:38:11 -07003804 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003805 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003806 case GL_BUFFER_MAP_POINTER:
3807 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003808
Geoff Lang496c02d2016-10-20 11:38:11 -07003809 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003810 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003811 return false;
3812 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003813
3814 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3815 // target bound to zero generate an INVALID_OPERATION error."
3816 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003817 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003818 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003819 context->handleError(InvalidOperation()
3820 << "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003821 return false;
3822 }
3823
Geoff Lang496c02d2016-10-20 11:38:11 -07003824 if (length)
3825 {
3826 *length = 1;
3827 }
3828
Olli Etuaho4f667482016-03-30 15:56:35 +03003829 return true;
3830}
3831
Corentin Wallez336129f2017-10-17 15:55:40 -04003832bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003833{
Corentin Walleze4477002017-12-01 14:39:58 -05003834 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003835 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003836 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003837 return false;
3838 }
3839
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003840 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003841
3842 if (buffer == nullptr || !buffer->isMapped())
3843 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003844 context->handleError(InvalidOperation() << "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003845 return false;
3846 }
3847
3848 return true;
3849}
3850
3851bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003852 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003853 GLintptr offset,
3854 GLsizeiptr length,
3855 GLbitfield access)
3856{
Corentin Walleze4477002017-12-01 14:39:58 -05003857 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003858 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003859 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003860 return false;
3861 }
3862
Brandon Jones6cad5662017-06-14 13:25:13 -07003863 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003864 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003865 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
3866 return false;
3867 }
3868
3869 if (length < 0)
3870 {
3871 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003872 return false;
3873 }
3874
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003875 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003876
3877 if (!buffer)
3878 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003879 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003880 return false;
3881 }
3882
3883 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003884 CheckedNumeric<size_t> checkedOffset(offset);
3885 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003886
Jamie Madille2e406c2016-06-02 13:04:10 -04003887 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003888 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003889 context->handleError(InvalidValue() << "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003890 return false;
3891 }
3892
3893 // Check for invalid bits in the mask
3894 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3895 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3896 GL_MAP_UNSYNCHRONIZED_BIT;
3897
3898 if (access & ~(allAccessBits))
3899 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003900 context->handleError(InvalidValue()
3901 << "Invalid access bits: 0x" << std::hex << std::uppercase << access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003902 return false;
3903 }
3904
3905 if (length == 0)
3906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003907 context->handleError(InvalidOperation() << "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003908 return false;
3909 }
3910
3911 if (buffer->isMapped())
3912 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003913 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003914 return false;
3915 }
3916
3917 // Check for invalid bit combinations
3918 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidOperation()
3921 << "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003922 return false;
3923 }
3924
3925 GLbitfield writeOnlyBits =
3926 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3927
3928 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003930 context->handleError(InvalidOperation()
3931 << "Invalid access bits when mapping buffer for reading: 0x"
3932 << std::hex << std::uppercase << access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003933 return false;
3934 }
3935
3936 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3937 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003938 context->handleError(
3939 InvalidOperation()
3940 << "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003941 return false;
3942 }
Geoff Lang79f71042017-08-14 16:43:43 -04003943
3944 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003945}
3946
3947bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003948 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003949 GLintptr offset,
3950 GLsizeiptr length)
3951{
Brandon Jones6cad5662017-06-14 13:25:13 -07003952 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003953 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003954 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
3955 return false;
3956 }
3957
3958 if (length < 0)
3959 {
3960 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003961 return false;
3962 }
3963
Corentin Walleze4477002017-12-01 14:39:58 -05003964 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003965 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003966 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003967 return false;
3968 }
3969
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003970 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003971
3972 if (buffer == nullptr)
3973 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003974 context->handleError(InvalidOperation() << "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003975 return false;
3976 }
3977
3978 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
3979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003980 context->handleError(InvalidOperation()
3981 << "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003982 return false;
3983 }
3984
3985 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003986 CheckedNumeric<size_t> checkedOffset(offset);
3987 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003988
Jamie Madille2e406c2016-06-02 13:04:10 -04003989 if (!checkedSize.IsValid() ||
3990 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003991 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003992 context->handleError(InvalidValue()
3993 << "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003994 return false;
3995 }
3996
3997 return true;
3998}
3999
Olli Etuaho41997e72016-03-10 13:38:39 +02004000bool ValidateGenOrDelete(Context *context, GLint n)
4001{
4002 if (n < 0)
4003 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004004 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004005 return false;
4006 }
4007 return true;
4008}
4009
Jamie Madill5b772312018-03-08 20:28:32 -05004010bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004011{
4012 if (!context->getExtensions().robustClientMemory)
4013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004014 context->handleError(InvalidOperation()
4015 << "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004016 return false;
4017 }
4018
4019 if (bufSize < 0)
4020 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004021 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004022 return false;
4023 }
4024
4025 return true;
4026}
4027
Jamie Madill5b772312018-03-08 20:28:32 -05004028bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004029{
4030 if (bufSize < numParams)
4031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004032 context->handleError(InvalidOperation() << numParams << " parameters are required but "
4033 << bufSize << " were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004034 return false;
4035 }
4036
4037 return true;
4038}
4039
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004040bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004041 GLenum target,
4042 GLenum attachment,
4043 GLenum pname,
4044 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004045{
Geoff Lange8afa902017-09-27 15:00:43 -04004046 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004048 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004049 return false;
4050 }
4051
4052 int clientVersion = context->getClientMajorVersion();
4053
4054 switch (pname)
4055 {
4056 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4057 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4058 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4059 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4060 break;
4061
Martin Radeve5285d22017-07-14 16:23:53 +03004062 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4063 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4064 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4065 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4066 if (clientVersion < 3 || !context->getExtensions().multiview)
4067 {
4068 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
4069 return false;
4070 }
4071 break;
4072
Geoff Langff5b2d52016-09-07 11:32:23 -04004073 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4074 if (clientVersion < 3 && !context->getExtensions().sRGB)
4075 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004076 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004077 return false;
4078 }
4079 break;
4080
4081 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4082 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4083 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4084 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4085 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4086 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4087 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4088 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4089 if (clientVersion < 3)
4090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004091 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004092 return false;
4093 }
4094 break;
4095
Jiawei Shaoa8802472018-05-28 11:17:47 +08004096 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4097 if (!context->getExtensions().geometryShader)
4098 {
4099 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
4100 return false;
4101 }
4102 break;
4103
Geoff Langff5b2d52016-09-07 11:32:23 -04004104 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004105 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004106 return false;
4107 }
4108
4109 // Determine if the attachment is a valid enum
4110 switch (attachment)
4111 {
4112 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004113 case GL_DEPTH:
4114 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004115 if (clientVersion < 3)
4116 {
Geoff Langfa125c92017-10-24 13:01:46 -04004117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004118 return false;
4119 }
4120 break;
4121
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004122 case GL_DEPTH_STENCIL_ATTACHMENT:
4123 if (clientVersion < 3 && !context->isWebGL1())
4124 {
4125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
4126 return false;
4127 }
4128 break;
4129
Geoff Langfa125c92017-10-24 13:01:46 -04004130 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004131 case GL_DEPTH_ATTACHMENT:
4132 case GL_STENCIL_ATTACHMENT:
4133 break;
4134
4135 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004136 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4137 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004138 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4139 {
Geoff Langfa125c92017-10-24 13:01:46 -04004140 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004141 return false;
4142 }
4143 break;
4144 }
4145
4146 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4147 ASSERT(framebuffer);
4148
4149 if (framebuffer->id() == 0)
4150 {
4151 if (clientVersion < 3)
4152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004154 return false;
4155 }
4156
4157 switch (attachment)
4158 {
4159 case GL_BACK:
4160 case GL_DEPTH:
4161 case GL_STENCIL:
4162 break;
4163
4164 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004166 return false;
4167 }
4168 }
4169 else
4170 {
4171 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4172 {
4173 // Valid attachment query
4174 }
4175 else
4176 {
4177 switch (attachment)
4178 {
4179 case GL_DEPTH_ATTACHMENT:
4180 case GL_STENCIL_ATTACHMENT:
4181 break;
4182
4183 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004184 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004186 context->handleError(InvalidOperation());
Geoff Langff5b2d52016-09-07 11:32:23 -04004187 return false;
4188 }
4189 break;
4190
4191 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004192 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004193 return false;
4194 }
4195 }
4196 }
4197
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004198 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004199 if (attachmentObject)
4200 {
4201 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4202 attachmentObject->type() == GL_TEXTURE ||
4203 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4204
4205 switch (pname)
4206 {
4207 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4208 if (attachmentObject->type() != GL_RENDERBUFFER &&
4209 attachmentObject->type() != GL_TEXTURE)
4210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004212 return false;
4213 }
4214 break;
4215
4216 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4217 if (attachmentObject->type() != GL_TEXTURE)
4218 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004220 return false;
4221 }
4222 break;
4223
4224 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4225 if (attachmentObject->type() != GL_TEXTURE)
4226 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004227 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004228 return false;
4229 }
4230 break;
4231
4232 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4233 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4234 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004235 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004236 return false;
4237 }
4238 break;
4239
4240 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4241 if (attachmentObject->type() != GL_TEXTURE)
4242 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004243 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004244 return false;
4245 }
4246 break;
4247
4248 default:
4249 break;
4250 }
4251 }
4252 else
4253 {
4254 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4255 // is NONE, then querying any other pname will generate INVALID_ENUM.
4256
4257 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4258 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4259 // INVALID_OPERATION for all other pnames
4260
4261 switch (pname)
4262 {
4263 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4264 break;
4265
4266 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4267 if (clientVersion < 3)
4268 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004269 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004270 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004271 return false;
4272 }
4273 break;
4274
4275 default:
4276 if (clientVersion < 3)
4277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004278 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004279 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004280 return false;
4281 }
4282 else
4283 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004284 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004285 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004286 return false;
4287 }
4288 }
4289 }
4290
Martin Radeve5285d22017-07-14 16:23:53 +03004291 if (numParams)
4292 {
4293 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4294 {
4295 // Only when the viewport offsets are queried we can have a varying number of output
4296 // parameters.
4297 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4298 *numParams = numViews * 2;
4299 }
4300 else
4301 {
4302 // For all other queries we can have only one output parameter.
4303 *numParams = 1;
4304 }
4305 }
4306
Geoff Langff5b2d52016-09-07 11:32:23 -04004307 return true;
4308}
4309
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004310bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004311 GLenum target,
4312 GLenum attachment,
4313 GLenum pname,
4314 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004315 GLsizei *length,
4316 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004317{
4318 if (!ValidateRobustEntryPoint(context, bufSize))
4319 {
4320 return false;
4321 }
4322
Brandon Jonesd1049182018-03-28 10:02:20 -07004323 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004324 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004325 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004326 {
4327 return false;
4328 }
4329
Brandon Jonesd1049182018-03-28 10:02:20 -07004330 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004331 {
4332 return false;
4333 }
4334
Brandon Jonesd1049182018-03-28 10:02:20 -07004335 SetRobustLengthParam(length, numParams);
4336
Geoff Langff5b2d52016-09-07 11:32:23 -04004337 return true;
4338}
4339
Jamie Madill5b772312018-03-08 20:28:32 -05004340bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004341 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004342 GLenum pname,
4343 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004344 GLsizei *length,
4345 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004346{
4347 if (!ValidateRobustEntryPoint(context, bufSize))
4348 {
4349 return false;
4350 }
4351
Brandon Jonesd1049182018-03-28 10:02:20 -07004352 GLsizei numParams = 0;
4353
4354 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004355 {
4356 return false;
4357 }
4358
Brandon Jonesd1049182018-03-28 10:02:20 -07004359 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004360 {
4361 return false;
4362 }
4363
Brandon Jonesd1049182018-03-28 10:02:20 -07004364 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004365 return true;
4366}
4367
Jamie Madill5b772312018-03-08 20:28:32 -05004368bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004369 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004370 GLenum pname,
4371 GLsizei bufSize,
4372 GLsizei *length,
4373 GLint64 *params)
4374{
Brandon Jonesd1049182018-03-28 10:02:20 -07004375 GLsizei numParams = 0;
4376
Geoff Langebebe1c2016-10-14 12:01:31 -04004377 if (!ValidateRobustEntryPoint(context, bufSize))
4378 {
4379 return false;
4380 }
4381
Brandon Jonesd1049182018-03-28 10:02:20 -07004382 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004383 {
4384 return false;
4385 }
4386
Brandon Jonesd1049182018-03-28 10:02:20 -07004387 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004388 {
4389 return false;
4390 }
4391
Brandon Jonesd1049182018-03-28 10:02:20 -07004392 SetRobustLengthParam(length, numParams);
4393
Geoff Langff5b2d52016-09-07 11:32:23 -04004394 return true;
4395}
4396
Jamie Madill5b772312018-03-08 20:28:32 -05004397bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004398{
4399 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004400 if (numParams)
4401 {
4402 *numParams = 1;
4403 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004404
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004405 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4406 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4407 ? GetValidProgramNoResolve(context, program)
4408 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004409 if (!programObject)
4410 {
4411 return false;
4412 }
4413
4414 switch (pname)
4415 {
4416 case GL_DELETE_STATUS:
4417 case GL_LINK_STATUS:
4418 case GL_VALIDATE_STATUS:
4419 case GL_INFO_LOG_LENGTH:
4420 case GL_ATTACHED_SHADERS:
4421 case GL_ACTIVE_ATTRIBUTES:
4422 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4423 case GL_ACTIVE_UNIFORMS:
4424 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4425 break;
4426
4427 case GL_PROGRAM_BINARY_LENGTH:
4428 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004430 context->handleError(InvalidEnum() << "Querying GL_PROGRAM_BINARY_LENGTH "
4431 "requires GL_OES_get_program_binary or "
4432 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004433 return false;
4434 }
4435 break;
4436
4437 case GL_ACTIVE_UNIFORM_BLOCKS:
4438 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4439 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4440 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4441 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4442 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4443 if (context->getClientMajorVersion() < 3)
4444 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004445 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004446 return false;
4447 }
4448 break;
4449
Yunchao He61afff12017-03-14 15:34:03 +08004450 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004451 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004452 if (context->getClientVersion() < Version(3, 1))
4453 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004454 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004455 return false;
4456 }
4457 break;
4458
Jiawei Shao6ae51612018-02-23 14:03:25 +08004459 case GL_COMPUTE_WORK_GROUP_SIZE:
4460 if (context->getClientVersion() < Version(3, 1))
4461 {
4462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
4463 return false;
4464 }
4465
4466 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4467 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4468 // program which has not been linked successfully, or which does not contain objects to
4469 // form a compute shader.
4470 if (!programObject->isLinked())
4471 {
4472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
4473 return false;
4474 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004475 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004476 {
4477 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveComputeShaderStage);
4478 return false;
4479 }
4480 break;
4481
Jiawei Shao447bfac2018-03-14 14:23:40 +08004482 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4483 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4484 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4485 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4486 if (!context->getExtensions().geometryShader)
4487 {
4488 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
4489 return false;
4490 }
4491
4492 // [EXT_geometry_shader] Chapter 7.12
4493 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4494 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4495 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4496 // successfully, or which does not contain objects to form a geometry shader.
4497 if (!programObject->isLinked())
4498 {
4499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
4500 return false;
4501 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004502 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004503 {
4504 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveGeometryShaderStage);
4505 return false;
4506 }
4507 break;
4508
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004509 case GL_COMPLETION_STATUS_KHR:
4510 if (!context->getExtensions().parallelShaderCompile)
4511 {
4512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
4513 return false;
4514 }
4515 break;
4516
Geoff Langff5b2d52016-09-07 11:32:23 -04004517 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004518 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004519 return false;
4520 }
4521
4522 return true;
4523}
4524
4525bool ValidateGetProgramivRobustANGLE(Context *context,
4526 GLuint program,
4527 GLenum pname,
4528 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004529 GLsizei *length,
4530 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004531{
4532 if (!ValidateRobustEntryPoint(context, bufSize))
4533 {
4534 return false;
4535 }
4536
Brandon Jonesd1049182018-03-28 10:02:20 -07004537 GLsizei numParams = 0;
4538
4539 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004540 {
4541 return false;
4542 }
4543
Brandon Jonesd1049182018-03-28 10:02:20 -07004544 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004545 {
4546 return false;
4547 }
4548
Brandon Jonesd1049182018-03-28 10:02:20 -07004549 SetRobustLengthParam(length, numParams);
4550
Geoff Langff5b2d52016-09-07 11:32:23 -04004551 return true;
4552}
4553
Geoff Lang740d9022016-10-07 11:20:52 -04004554bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4555 GLenum target,
4556 GLenum pname,
4557 GLsizei bufSize,
4558 GLsizei *length,
4559 GLint *params)
4560{
4561 if (!ValidateRobustEntryPoint(context, bufSize))
4562 {
4563 return false;
4564 }
4565
Brandon Jonesd1049182018-03-28 10:02:20 -07004566 GLsizei numParams = 0;
4567
4568 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004569 {
4570 return false;
4571 }
4572
Brandon Jonesd1049182018-03-28 10:02:20 -07004573 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004574 {
4575 return false;
4576 }
4577
Brandon Jonesd1049182018-03-28 10:02:20 -07004578 SetRobustLengthParam(length, numParams);
4579
Geoff Lang740d9022016-10-07 11:20:52 -04004580 return true;
4581}
4582
Geoff Langd7d0ed32016-10-07 11:33:51 -04004583bool ValidateGetShaderivRobustANGLE(Context *context,
4584 GLuint shader,
4585 GLenum pname,
4586 GLsizei bufSize,
4587 GLsizei *length,
4588 GLint *params)
4589{
4590 if (!ValidateRobustEntryPoint(context, bufSize))
4591 {
4592 return false;
4593 }
4594
Brandon Jonesd1049182018-03-28 10:02:20 -07004595 GLsizei numParams = 0;
4596
4597 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004598 {
4599 return false;
4600 }
4601
Brandon Jonesd1049182018-03-28 10:02:20 -07004602 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004603 {
4604 return false;
4605 }
4606
Brandon Jonesd1049182018-03-28 10:02:20 -07004607 SetRobustLengthParam(length, numParams);
4608
Geoff Langd7d0ed32016-10-07 11:33:51 -04004609 return true;
4610}
4611
Geoff Langc1984ed2016-10-07 12:41:00 -04004612bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004613 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004614 GLenum pname,
4615 GLsizei bufSize,
4616 GLsizei *length,
4617 GLfloat *params)
4618{
4619 if (!ValidateRobustEntryPoint(context, bufSize))
4620 {
4621 return false;
4622 }
4623
Brandon Jonesd1049182018-03-28 10:02:20 -07004624 GLsizei numParams = 0;
4625
4626 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004627 {
4628 return false;
4629 }
4630
Brandon Jonesd1049182018-03-28 10:02:20 -07004631 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004632 {
4633 return false;
4634 }
4635
Brandon Jonesd1049182018-03-28 10:02:20 -07004636 SetRobustLengthParam(length, numParams);
4637
Geoff Langc1984ed2016-10-07 12:41:00 -04004638 return true;
4639}
4640
Geoff Langc1984ed2016-10-07 12:41:00 -04004641bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004642 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004643 GLenum pname,
4644 GLsizei bufSize,
4645 GLsizei *length,
4646 GLint *params)
4647{
Brandon Jonesd1049182018-03-28 10:02:20 -07004648
Geoff Langc1984ed2016-10-07 12:41:00 -04004649 if (!ValidateRobustEntryPoint(context, bufSize))
4650 {
4651 return false;
4652 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004653 GLsizei numParams = 0;
4654 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004655 {
4656 return false;
4657 }
4658
Brandon Jonesd1049182018-03-28 10:02:20 -07004659 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004660 {
4661 return false;
4662 }
4663
Brandon Jonesd1049182018-03-28 10:02:20 -07004664 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004665 return true;
4666}
4667
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004668bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4669 TextureType target,
4670 GLenum pname,
4671 GLsizei bufSize,
4672 GLsizei *length,
4673 GLint *params)
4674{
4675 UNIMPLEMENTED();
4676 return false;
4677}
4678
4679bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4680 TextureType target,
4681 GLenum pname,
4682 GLsizei bufSize,
4683 GLsizei *length,
4684 GLuint *params)
4685{
4686 UNIMPLEMENTED();
4687 return false;
4688}
4689
Geoff Langc1984ed2016-10-07 12:41:00 -04004690bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004691 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004692 GLenum pname,
4693 GLsizei bufSize,
4694 const GLfloat *params)
4695{
4696 if (!ValidateRobustEntryPoint(context, bufSize))
4697 {
4698 return false;
4699 }
4700
4701 return ValidateTexParameterBase(context, target, pname, bufSize, params);
4702}
4703
Geoff Langc1984ed2016-10-07 12:41:00 -04004704bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004705 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004706 GLenum pname,
4707 GLsizei bufSize,
4708 const GLint *params)
4709{
4710 if (!ValidateRobustEntryPoint(context, bufSize))
4711 {
4712 return false;
4713 }
4714
4715 return ValidateTexParameterBase(context, target, pname, bufSize, params);
4716}
4717
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004718bool ValidateTexParameterIivRobustANGLE(Context *context,
4719 TextureType target,
4720 GLenum pname,
4721 GLsizei bufSize,
4722 const GLint *params)
4723{
4724 UNIMPLEMENTED();
4725 return false;
4726}
4727
4728bool ValidateTexParameterIuivRobustANGLE(Context *context,
4729 TextureType target,
4730 GLenum pname,
4731 GLsizei bufSize,
4732 const GLuint *params)
4733{
4734 UNIMPLEMENTED();
4735 return false;
4736}
4737
Geoff Langc1984ed2016-10-07 12:41:00 -04004738bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4739 GLuint sampler,
4740 GLenum pname,
4741 GLuint bufSize,
4742 GLsizei *length,
4743 GLfloat *params)
4744{
4745 if (!ValidateRobustEntryPoint(context, bufSize))
4746 {
4747 return false;
4748 }
4749
Brandon Jonesd1049182018-03-28 10:02:20 -07004750 GLsizei numParams = 0;
4751
4752 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004753 {
4754 return false;
4755 }
4756
Brandon Jonesd1049182018-03-28 10:02:20 -07004757 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004758 {
4759 return false;
4760 }
4761
Brandon Jonesd1049182018-03-28 10:02:20 -07004762 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004763 return true;
4764}
4765
Geoff Langc1984ed2016-10-07 12:41:00 -04004766bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4767 GLuint sampler,
4768 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004769 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004770 GLsizei *length,
4771 GLint *params)
4772{
4773 if (!ValidateRobustEntryPoint(context, bufSize))
4774 {
4775 return false;
4776 }
4777
Brandon Jonesd1049182018-03-28 10:02:20 -07004778 GLsizei numParams = 0;
4779
4780 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004781 {
4782 return false;
4783 }
4784
Brandon Jonesd1049182018-03-28 10:02:20 -07004785 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004786 {
4787 return false;
4788 }
4789
Brandon Jonesd1049182018-03-28 10:02:20 -07004790 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004791 return true;
4792}
4793
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004794bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4795 GLuint sampler,
4796 GLenum pname,
4797 GLsizei bufSize,
4798 GLsizei *length,
4799 GLint *params)
4800{
4801 UNIMPLEMENTED();
4802 return false;
4803}
4804
4805bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4806 GLuint sampler,
4807 GLenum pname,
4808 GLsizei bufSize,
4809 GLsizei *length,
4810 GLuint *params)
4811{
4812 UNIMPLEMENTED();
4813 return false;
4814}
4815
Geoff Langc1984ed2016-10-07 12:41:00 -04004816bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4817 GLuint sampler,
4818 GLenum pname,
4819 GLsizei bufSize,
4820 const GLfloat *params)
4821{
4822 if (!ValidateRobustEntryPoint(context, bufSize))
4823 {
4824 return false;
4825 }
4826
4827 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
4828}
4829
Geoff Langc1984ed2016-10-07 12:41:00 -04004830bool ValidateSamplerParameterivRobustANGLE(Context *context,
4831 GLuint sampler,
4832 GLenum pname,
4833 GLsizei bufSize,
4834 const GLint *params)
4835{
4836 if (!ValidateRobustEntryPoint(context, bufSize))
4837 {
4838 return false;
4839 }
4840
4841 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
4842}
4843
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004844bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4845 GLuint sampler,
4846 GLenum pname,
4847 GLsizei bufSize,
4848 const GLint *param)
4849{
4850 UNIMPLEMENTED();
4851 return false;
4852}
4853
4854bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4855 GLuint sampler,
4856 GLenum pname,
4857 GLsizei bufSize,
4858 const GLuint *param)
4859{
4860 UNIMPLEMENTED();
4861 return false;
4862}
4863
Geoff Lang0b031062016-10-13 14:30:04 -04004864bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4865 GLuint index,
4866 GLenum pname,
4867 GLsizei bufSize,
4868 GLsizei *length,
4869 GLfloat *params)
4870{
4871 if (!ValidateRobustEntryPoint(context, bufSize))
4872 {
4873 return false;
4874 }
4875
Brandon Jonesd1049182018-03-28 10:02:20 -07004876 GLsizei writeLength = 0;
4877
4878 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004879 {
4880 return false;
4881 }
4882
Brandon Jonesd1049182018-03-28 10:02:20 -07004883 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004884 {
4885 return false;
4886 }
4887
Brandon Jonesd1049182018-03-28 10:02:20 -07004888 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004889 return true;
4890}
4891
Geoff Lang0b031062016-10-13 14:30:04 -04004892bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4893 GLuint index,
4894 GLenum pname,
4895 GLsizei bufSize,
4896 GLsizei *length,
4897 GLint *params)
4898{
4899 if (!ValidateRobustEntryPoint(context, bufSize))
4900 {
4901 return false;
4902 }
4903
Brandon Jonesd1049182018-03-28 10:02:20 -07004904 GLsizei writeLength = 0;
4905
4906 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004907 {
4908 return false;
4909 }
4910
Brandon Jonesd1049182018-03-28 10:02:20 -07004911 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004912 {
4913 return false;
4914 }
4915
Brandon Jonesd1049182018-03-28 10:02:20 -07004916 SetRobustLengthParam(length, writeLength);
4917
Geoff Lang0b031062016-10-13 14:30:04 -04004918 return true;
4919}
4920
Geoff Lang0b031062016-10-13 14:30:04 -04004921bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4922 GLuint index,
4923 GLenum pname,
4924 GLsizei bufSize,
4925 GLsizei *length,
4926 void **pointer)
4927{
4928 if (!ValidateRobustEntryPoint(context, bufSize))
4929 {
4930 return false;
4931 }
4932
Brandon Jonesd1049182018-03-28 10:02:20 -07004933 GLsizei writeLength = 0;
4934
4935 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004936 {
4937 return false;
4938 }
4939
Brandon Jonesd1049182018-03-28 10:02:20 -07004940 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004941 {
4942 return false;
4943 }
4944
Brandon Jonesd1049182018-03-28 10:02:20 -07004945 SetRobustLengthParam(length, writeLength);
4946
Geoff Lang0b031062016-10-13 14:30:04 -04004947 return true;
4948}
4949
Geoff Lang0b031062016-10-13 14:30:04 -04004950bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4951 GLuint index,
4952 GLenum pname,
4953 GLsizei bufSize,
4954 GLsizei *length,
4955 GLint *params)
4956{
4957 if (!ValidateRobustEntryPoint(context, bufSize))
4958 {
4959 return false;
4960 }
4961
Brandon Jonesd1049182018-03-28 10:02:20 -07004962 GLsizei writeLength = 0;
4963
4964 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004965 {
4966 return false;
4967 }
4968
Brandon Jonesd1049182018-03-28 10:02:20 -07004969 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004970 {
4971 return false;
4972 }
4973
Brandon Jonesd1049182018-03-28 10:02:20 -07004974 SetRobustLengthParam(length, writeLength);
4975
Geoff Lang0b031062016-10-13 14:30:04 -04004976 return true;
4977}
4978
Geoff Lang0b031062016-10-13 14:30:04 -04004979bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
4980 GLuint index,
4981 GLenum pname,
4982 GLsizei bufSize,
4983 GLsizei *length,
4984 GLuint *params)
4985{
4986 if (!ValidateRobustEntryPoint(context, bufSize))
4987 {
4988 return false;
4989 }
4990
Brandon Jonesd1049182018-03-28 10:02:20 -07004991 GLsizei writeLength = 0;
4992
4993 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004994 {
4995 return false;
4996 }
4997
Brandon Jonesd1049182018-03-28 10:02:20 -07004998 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004999 {
5000 return false;
5001 }
5002
Brandon Jonesd1049182018-03-28 10:02:20 -07005003 SetRobustLengthParam(length, writeLength);
5004
Geoff Lang0b031062016-10-13 14:30:04 -04005005 return true;
5006}
5007
Geoff Lang6899b872016-10-14 11:30:13 -04005008bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5009 GLuint program,
5010 GLuint uniformBlockIndex,
5011 GLenum pname,
5012 GLsizei bufSize,
5013 GLsizei *length,
5014 GLint *params)
5015{
5016 if (!ValidateRobustEntryPoint(context, bufSize))
5017 {
5018 return false;
5019 }
5020
Brandon Jonesd1049182018-03-28 10:02:20 -07005021 GLsizei writeLength = 0;
5022
5023 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5024 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005025 {
5026 return false;
5027 }
5028
Brandon Jonesd1049182018-03-28 10:02:20 -07005029 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005030 {
5031 return false;
5032 }
5033
Brandon Jonesd1049182018-03-28 10:02:20 -07005034 SetRobustLengthParam(length, writeLength);
5035
Geoff Lang6899b872016-10-14 11:30:13 -04005036 return true;
5037}
5038
Brandon Jones416aaf92018-04-10 08:10:16 -07005039bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005040 GLenum target,
5041 GLenum internalformat,
5042 GLenum pname,
5043 GLsizei bufSize,
5044 GLsizei *length,
5045 GLint *params)
5046{
5047 if (!ValidateRobustEntryPoint(context, bufSize))
5048 {
5049 return false;
5050 }
5051
Brandon Jonesd1049182018-03-28 10:02:20 -07005052 GLsizei numParams = 0;
5053
5054 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5055 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005056 {
5057 return false;
5058 }
5059
Brandon Jonesd1049182018-03-28 10:02:20 -07005060 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005061 {
5062 return false;
5063 }
5064
Brandon Jonesd1049182018-03-28 10:02:20 -07005065 SetRobustLengthParam(length, numParams);
5066
Geoff Lang0a9661f2016-10-20 10:59:20 -07005067 return true;
5068}
5069
Jamie Madill5b772312018-03-08 20:28:32 -05005070bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005071 GLuint attribIndex,
5072 GLint size,
5073 GLenum type,
5074 GLboolean pureInteger)
5075{
5076 const Caps &caps = context->getCaps();
5077 if (attribIndex >= caps.maxVertexAttributes)
5078 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005079 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005080 return false;
5081 }
5082
5083 if (size < 1 || size > 4)
5084 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005085 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005086 return false;
Shao80957d92017-02-20 21:25:59 +08005087 }
5088
5089 switch (type)
5090 {
5091 case GL_BYTE:
5092 case GL_UNSIGNED_BYTE:
5093 case GL_SHORT:
5094 case GL_UNSIGNED_SHORT:
5095 break;
5096
5097 case GL_INT:
5098 case GL_UNSIGNED_INT:
5099 if (context->getClientMajorVersion() < 3)
5100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005101 context->handleError(InvalidEnum()
5102 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005103 return false;
5104 }
5105 break;
5106
5107 case GL_FIXED:
5108 case GL_FLOAT:
5109 if (pureInteger)
5110 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005111 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005112 return false;
5113 }
5114 break;
5115
5116 case GL_HALF_FLOAT:
5117 if (context->getClientMajorVersion() < 3)
5118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005119 context->handleError(InvalidEnum()
5120 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005121 return false;
5122 }
5123 if (pureInteger)
5124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005126 return false;
5127 }
5128 break;
5129
5130 case GL_INT_2_10_10_10_REV:
5131 case GL_UNSIGNED_INT_2_10_10_10_REV:
5132 if (context->getClientMajorVersion() < 3)
5133 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005134 context->handleError(InvalidEnum()
5135 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005136 return false;
5137 }
5138 if (pureInteger)
5139 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005140 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005141 return false;
5142 }
5143 if (size != 4)
5144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005145 context->handleError(InvalidOperation() << "Type is INT_2_10_10_10_REV or "
5146 "UNSIGNED_INT_2_10_10_10_REV and "
5147 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005148 return false;
5149 }
5150 break;
5151
5152 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005153 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
Shao80957d92017-02-20 21:25:59 +08005154 return false;
5155 }
5156
5157 return true;
5158}
5159
Geoff Lang76e65652017-03-27 14:58:02 -04005160// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5161// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5162// specified clear value and the type of a buffer that is being cleared generates an
5163// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005164bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005165 GLint drawbuffer,
5166 const GLenum *validComponentTypes,
5167 size_t validComponentTypeCount)
5168{
5169 const FramebufferAttachment *attachment =
5170 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5171 if (attachment)
5172 {
5173 GLenum componentType = attachment->getFormat().info->componentType;
5174 const GLenum *end = validComponentTypes + validComponentTypeCount;
5175 if (std::find(validComponentTypes, end, componentType) == end)
5176 {
5177 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005178 InvalidOperation()
5179 << "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005180 return false;
5181 }
5182 }
5183
5184 return true;
5185}
5186
Jamie Madill5b772312018-03-08 20:28:32 -05005187bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005188{
5189 if (!ValidateRobustEntryPoint(context, dataSize))
5190 {
5191 return false;
5192 }
5193
Jamie Madill43da7c42018-08-01 11:34:49 -04005194 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005195 if (pixelUnpackBuffer == nullptr)
5196 {
5197 if (dataSize < imageSize)
5198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005199 context->handleError(InvalidOperation() << "dataSize must be at least " << imageSize);
Corentin Wallezb2931602017-04-11 15:58:57 -04005200 }
5201 }
5202 return true;
5203}
5204
Jamie Madill5b772312018-03-08 20:28:32 -05005205bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005206 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005207 GLenum pname,
5208 bool pointerVersion,
5209 GLsizei *numParams)
5210{
5211 if (numParams)
5212 {
5213 *numParams = 0;
5214 }
5215
Corentin Walleze4477002017-12-01 14:39:58 -05005216 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005218 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005219 return false;
5220 }
5221
5222 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5223 if (!buffer)
5224 {
5225 // A null buffer means that "0" is bound to the requested buffer target
Brandon Jones6cad5662017-06-14 13:25:13 -07005226 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005227 return false;
5228 }
5229
5230 const Extensions &extensions = context->getExtensions();
5231
5232 switch (pname)
5233 {
5234 case GL_BUFFER_USAGE:
5235 case GL_BUFFER_SIZE:
5236 break;
5237
5238 case GL_BUFFER_ACCESS_OES:
5239 if (!extensions.mapBuffer)
5240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005241 context->handleError(InvalidEnum()
5242 << "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005243 return false;
5244 }
5245 break;
5246
5247 case GL_BUFFER_MAPPED:
5248 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5249 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5250 !extensions.mapBufferRange)
5251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005252 context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0, "
5253 "GL_OES_mapbuffer or "
5254 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005255 return false;
5256 }
5257 break;
5258
5259 case GL_BUFFER_MAP_POINTER:
5260 if (!pointerVersion)
5261 {
5262 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005263 InvalidEnum()
5264 << "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005265 return false;
5266 }
5267 break;
5268
5269 case GL_BUFFER_ACCESS_FLAGS:
5270 case GL_BUFFER_MAP_OFFSET:
5271 case GL_BUFFER_MAP_LENGTH:
5272 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5273 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005274 context->handleError(InvalidEnum()
5275 << "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005276 return false;
5277 }
5278 break;
5279
5280 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005281 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005282 return false;
5283 }
5284
5285 // All buffer parameter queries return one value.
5286 if (numParams)
5287 {
5288 *numParams = 1;
5289 }
5290
5291 return true;
5292}
5293
5294bool ValidateGetRenderbufferParameterivBase(Context *context,
5295 GLenum target,
5296 GLenum pname,
5297 GLsizei *length)
5298{
5299 if (length)
5300 {
5301 *length = 0;
5302 }
5303
5304 if (target != GL_RENDERBUFFER)
5305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005306 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005307 return false;
5308 }
5309
5310 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5311 if (renderbuffer == nullptr)
5312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005313 ANGLE_VALIDATION_ERR(context, InvalidOperation(), RenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005314 return false;
5315 }
5316
5317 switch (pname)
5318 {
5319 case GL_RENDERBUFFER_WIDTH:
5320 case GL_RENDERBUFFER_HEIGHT:
5321 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5322 case GL_RENDERBUFFER_RED_SIZE:
5323 case GL_RENDERBUFFER_GREEN_SIZE:
5324 case GL_RENDERBUFFER_BLUE_SIZE:
5325 case GL_RENDERBUFFER_ALPHA_SIZE:
5326 case GL_RENDERBUFFER_DEPTH_SIZE:
5327 case GL_RENDERBUFFER_STENCIL_SIZE:
5328 break;
5329
5330 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5331 if (!context->getExtensions().framebufferMultisample)
5332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005333 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005334 return false;
5335 }
5336 break;
5337
5338 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005339 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005340 return false;
5341 }
5342
5343 if (length)
5344 {
5345 *length = 1;
5346 }
5347 return true;
5348}
5349
5350bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5351{
5352 if (length)
5353 {
5354 *length = 0;
5355 }
5356
5357 if (GetValidShader(context, shader) == nullptr)
5358 {
5359 return false;
5360 }
5361
5362 switch (pname)
5363 {
5364 case GL_SHADER_TYPE:
5365 case GL_DELETE_STATUS:
5366 case GL_COMPILE_STATUS:
5367 case GL_INFO_LOG_LENGTH:
5368 case GL_SHADER_SOURCE_LENGTH:
5369 break;
5370
5371 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5372 if (!context->getExtensions().translatedShaderSource)
5373 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005374 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005375 return false;
5376 }
5377 break;
5378
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005379 case GL_COMPLETION_STATUS_KHR:
5380 if (!context->getExtensions().parallelShaderCompile)
5381 {
5382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
5383 return false;
5384 }
5385 break;
5386
Jamie Madillbe849e42017-05-02 15:49:00 -04005387 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005388 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005389 return false;
5390 }
5391
5392 if (length)
5393 {
5394 *length = 1;
5395 }
5396 return true;
5397}
5398
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005399bool ValidateGetTexParameterBase(Context *context,
5400 TextureType target,
5401 GLenum pname,
5402 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005403{
5404 if (length)
5405 {
5406 *length = 0;
5407 }
5408
5409 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5410 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005411 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005412 return false;
5413 }
5414
5415 if (context->getTargetTexture(target) == nullptr)
5416 {
5417 // Should only be possible for external textures
Brandon Jones6cad5662017-06-14 13:25:13 -07005418 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005419 return false;
5420 }
5421
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005422 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5423 {
5424 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5425 return false;
5426 }
5427
Jamie Madillbe849e42017-05-02 15:49:00 -04005428 switch (pname)
5429 {
5430 case GL_TEXTURE_MAG_FILTER:
5431 case GL_TEXTURE_MIN_FILTER:
5432 case GL_TEXTURE_WRAP_S:
5433 case GL_TEXTURE_WRAP_T:
5434 break;
5435
5436 case GL_TEXTURE_USAGE_ANGLE:
5437 if (!context->getExtensions().textureUsage)
5438 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005439 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005440 return false;
5441 }
5442 break;
5443
5444 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005445 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005446 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005447 return false;
5448 }
5449 break;
5450
5451 case GL_TEXTURE_IMMUTABLE_FORMAT:
5452 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005454 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005455 return false;
5456 }
5457 break;
5458
5459 case GL_TEXTURE_WRAP_R:
5460 case GL_TEXTURE_IMMUTABLE_LEVELS:
5461 case GL_TEXTURE_SWIZZLE_R:
5462 case GL_TEXTURE_SWIZZLE_G:
5463 case GL_TEXTURE_SWIZZLE_B:
5464 case GL_TEXTURE_SWIZZLE_A:
5465 case GL_TEXTURE_BASE_LEVEL:
5466 case GL_TEXTURE_MAX_LEVEL:
5467 case GL_TEXTURE_MIN_LOD:
5468 case GL_TEXTURE_MAX_LOD:
5469 case GL_TEXTURE_COMPARE_MODE:
5470 case GL_TEXTURE_COMPARE_FUNC:
5471 if (context->getClientMajorVersion() < 3)
5472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005473 context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005474 return false;
5475 }
5476 break;
5477
5478 case GL_TEXTURE_SRGB_DECODE_EXT:
5479 if (!context->getExtensions().textureSRGBDecode)
5480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005481 context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005482 return false;
5483 }
5484 break;
5485
Yunchao Hebacaa712018-01-30 14:01:39 +08005486 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5487 if (context->getClientVersion() < Version(3, 1))
5488 {
5489 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
5490 return false;
5491 }
5492 break;
5493
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005494 case GL_GENERATE_MIPMAP:
5495 case GL_TEXTURE_CROP_RECT_OES:
5496 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5497 // after GL_OES_draw_texture functionality implemented
5498 if (context->getClientMajorVersion() > 1)
5499 {
5500 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
5501 return false;
5502 }
5503 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005504 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005505 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005506 return false;
5507 }
5508
5509 if (length)
5510 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005511 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005512 }
5513 return true;
5514}
5515
5516bool ValidateGetVertexAttribBase(Context *context,
5517 GLuint index,
5518 GLenum pname,
5519 GLsizei *length,
5520 bool pointer,
5521 bool pureIntegerEntryPoint)
5522{
5523 if (length)
5524 {
5525 *length = 0;
5526 }
5527
5528 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5529 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005530 context->handleError(InvalidOperation() << "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005531 return false;
5532 }
5533
5534 if (index >= context->getCaps().maxVertexAttributes)
5535 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005536 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005537 return false;
5538 }
5539
5540 if (pointer)
5541 {
5542 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005544 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005545 return false;
5546 }
5547 }
5548 else
5549 {
5550 switch (pname)
5551 {
5552 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5553 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5554 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5555 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5556 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5557 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5558 case GL_CURRENT_VERTEX_ATTRIB:
5559 break;
5560
5561 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5562 static_assert(
5563 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5564 "ANGLE extension enums not equal to GL enums.");
5565 if (context->getClientMajorVersion() < 3 &&
5566 !context->getExtensions().instancedArrays)
5567 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005568 context->handleError(InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5569 "requires OpenGL ES 3.0 or "
5570 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005571 return false;
5572 }
5573 break;
5574
5575 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5576 if (context->getClientMajorVersion() < 3)
5577 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005578 context->handleError(
5579 InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005580 return false;
5581 }
5582 break;
5583
5584 case GL_VERTEX_ATTRIB_BINDING:
5585 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5586 if (context->getClientVersion() < ES_3_1)
5587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005588 context->handleError(InvalidEnum()
5589 << "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005590 return false;
5591 }
5592 break;
5593
5594 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005596 return false;
5597 }
5598 }
5599
5600 if (length)
5601 {
5602 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5603 {
5604 *length = 4;
5605 }
5606 else
5607 {
5608 *length = 1;
5609 }
5610 }
5611
5612 return true;
5613}
5614
Jamie Madill4928b7c2017-06-20 12:57:39 -04005615bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005616 GLint x,
5617 GLint y,
5618 GLsizei width,
5619 GLsizei height,
5620 GLenum format,
5621 GLenum type,
5622 GLsizei bufSize,
5623 GLsizei *length,
5624 GLsizei *columns,
5625 GLsizei *rows,
5626 void *pixels)
5627{
5628 if (length != nullptr)
5629 {
5630 *length = 0;
5631 }
5632 if (rows != nullptr)
5633 {
5634 *rows = 0;
5635 }
5636 if (columns != nullptr)
5637 {
5638 *columns = 0;
5639 }
5640
5641 if (width < 0 || height < 0)
5642 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005643 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005644 return false;
5645 }
5646
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005647 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005648
Jamie Madill427064d2018-04-13 16:20:34 -04005649 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005650 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005651 return false;
5652 }
5653
Jamie Madille98b1b52018-03-08 09:47:23 -05005654 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005655 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005656 return false;
5657 }
5658
Jamie Madill690c8eb2018-03-12 15:20:03 -04005659 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005660 ASSERT(framebuffer);
5661
5662 if (framebuffer->getReadBufferState() == GL_NONE)
5663 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005665 return false;
5666 }
5667
5668 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5669 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5670 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5671 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5672 // situation is an application error that would lead to a crash in ANGLE.
5673 if (readBuffer == nullptr)
5674 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005675 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005676 return false;
5677 }
5678
Martin Radev28031682017-07-28 14:47:56 +03005679 // ANGLE_multiview, Revision 1:
5680 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005681 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5682 // in the current read framebuffer is more than one.
5683 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005684 {
5685 context->handleError(InvalidFramebufferOperation()
5686 << "Attempting to read from a multi-view framebuffer.");
5687 return false;
5688 }
5689
Geoff Lang280ba992017-04-18 16:30:58 -04005690 if (context->getExtensions().webglCompatibility)
5691 {
5692 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5693 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5694 // and type before validating the combination of format and type. However, the
5695 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5696 // verifies that GL_INVALID_OPERATION is generated.
5697 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5698 // dEQP/WebGL.
5699 if (!ValidReadPixelsFormatEnum(context, format))
5700 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005701 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005702 return false;
5703 }
5704
5705 if (!ValidReadPixelsTypeEnum(context, type))
5706 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005707 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005708 return false;
5709 }
5710 }
5711
Jamie Madill690c8eb2018-03-12 15:20:03 -04005712 GLenum currentFormat = GL_NONE;
5713 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5714
5715 GLenum currentType = GL_NONE;
5716 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5717
Jamie Madillbe849e42017-05-02 15:49:00 -04005718 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5719
5720 bool validFormatTypeCombination =
5721 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5722
5723 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5724 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005725 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005726 return false;
5727 }
5728
5729 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005730 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005731 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5732 {
5733 // ...the buffer object's data store is currently mapped.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005734 context->handleError(InvalidOperation() << "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005735 return false;
5736 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005737 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5738 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5739 {
5740 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelPackBufferBoundForTransformFeedback);
5741 return false;
5742 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005743
5744 // .. the data would be packed to the buffer object such that the memory writes required
5745 // would exceed the data store size.
5746 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005747 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005748 const auto &pack = context->getGLState().getPackState();
5749
Jamie Madillca2ff382018-07-11 09:01:17 -04005750 GLuint endByte = 0;
5751 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005752 {
Jamie Madillca2ff382018-07-11 09:01:17 -04005753 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005754 return false;
5755 }
5756
Jamie Madillbe849e42017-05-02 15:49:00 -04005757 if (bufSize >= 0)
5758 {
5759 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5760 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005761 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005762 return false;
5763 }
5764 }
5765
5766 if (pixelPackBuffer != nullptr)
5767 {
5768 CheckedNumeric<size_t> checkedEndByte(endByte);
5769 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5770 checkedEndByte += checkedOffset;
5771
5772 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5773 {
5774 // Overflow past the end of the buffer
Brandon Jones6cad5662017-06-14 13:25:13 -07005775 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005776 return false;
5777 }
5778 }
5779
5780 if (pixelPackBuffer == nullptr && length != nullptr)
5781 {
5782 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5783 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005784 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005785 return false;
5786 }
5787
5788 *length = static_cast<GLsizei>(endByte);
5789 }
5790
Geoff Langa953b522018-02-21 16:56:23 -05005791 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005792 angle::CheckedNumeric<int> clippedExtent(length);
5793 if (start < 0)
5794 {
5795 // "subtract" the area that is less than 0
5796 clippedExtent += start;
5797 }
5798
Geoff Langa953b522018-02-21 16:56:23 -05005799 angle::CheckedNumeric<int> readExtent = start;
5800 readExtent += length;
5801 if (!readExtent.IsValid())
5802 {
5803 return false;
5804 }
5805
5806 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005807 {
5808 // Subtract the region to the right of the read buffer
5809 clippedExtent -= (readExtent - bufferSize);
5810 }
5811
5812 if (!clippedExtent.IsValid())
5813 {
Geoff Langa953b522018-02-21 16:56:23 -05005814 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005815 }
5816
Geoff Langa953b522018-02-21 16:56:23 -05005817 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5818 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005819 };
5820
Geoff Langa953b522018-02-21 16:56:23 -05005821 GLsizei writtenColumns = 0;
5822 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5823 {
5824 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
5825 return false;
5826 }
5827
5828 GLsizei writtenRows = 0;
5829 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5830 {
5831 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
5832 return false;
5833 }
5834
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 if (columns != nullptr)
5836 {
Geoff Langa953b522018-02-21 16:56:23 -05005837 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005838 }
5839
5840 if (rows != nullptr)
5841 {
Geoff Langa953b522018-02-21 16:56:23 -05005842 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005843 }
5844
5845 return true;
5846}
5847
5848template <typename ParamType>
5849bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005850 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005851 GLenum pname,
5852 GLsizei bufSize,
5853 const ParamType *params)
5854{
5855 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5856 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005857 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005858 return false;
5859 }
5860
5861 if (context->getTargetTexture(target) == nullptr)
5862 {
5863 // Should only be possible for external textures
Brandon Jones6cad5662017-06-14 13:25:13 -07005864 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005865 return false;
5866 }
5867
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005868 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005869 if (bufSize >= 0 && bufSize < minBufSize)
5870 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005871 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005872 return false;
5873 }
5874
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005875 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5876 {
5877 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5878 return false;
5879 }
5880
Jamie Madillbe849e42017-05-02 15:49:00 -04005881 switch (pname)
5882 {
5883 case GL_TEXTURE_WRAP_R:
5884 case GL_TEXTURE_SWIZZLE_R:
5885 case GL_TEXTURE_SWIZZLE_G:
5886 case GL_TEXTURE_SWIZZLE_B:
5887 case GL_TEXTURE_SWIZZLE_A:
5888 case GL_TEXTURE_BASE_LEVEL:
5889 case GL_TEXTURE_MAX_LEVEL:
5890 case GL_TEXTURE_COMPARE_MODE:
5891 case GL_TEXTURE_COMPARE_FUNC:
5892 case GL_TEXTURE_MIN_LOD:
5893 case GL_TEXTURE_MAX_LOD:
5894 if (context->getClientMajorVersion() < 3)
5895 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005896 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005897 return false;
5898 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005899 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005900 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005901 context->handleError(InvalidEnum() << "ES3 texture parameters are not "
5902 "available without "
5903 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005904 return false;
5905 }
5906 break;
5907
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005908 case GL_GENERATE_MIPMAP:
5909 case GL_TEXTURE_CROP_RECT_OES:
5910 if (context->getClientMajorVersion() > 1)
5911 {
5912 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
5913 return false;
5914 }
5915 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005916 default:
5917 break;
5918 }
5919
Olli Etuahod310a432018-08-24 15:40:23 +03005920 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005921 {
5922 switch (pname)
5923 {
5924 case GL_TEXTURE_MIN_FILTER:
5925 case GL_TEXTURE_MAG_FILTER:
5926 case GL_TEXTURE_WRAP_S:
5927 case GL_TEXTURE_WRAP_T:
5928 case GL_TEXTURE_WRAP_R:
5929 case GL_TEXTURE_MIN_LOD:
5930 case GL_TEXTURE_MAX_LOD:
5931 case GL_TEXTURE_COMPARE_MODE:
5932 case GL_TEXTURE_COMPARE_FUNC:
5933 context->handleError(InvalidEnum()
5934 << "Invalid parameter for 2D multisampled textures.");
5935 return false;
5936 }
5937 }
5938
Jamie Madillbe849e42017-05-02 15:49:00 -04005939 switch (pname)
5940 {
5941 case GL_TEXTURE_WRAP_S:
5942 case GL_TEXTURE_WRAP_T:
5943 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005944 {
5945 bool restrictedWrapModes =
5946 target == TextureType::External || target == TextureType::Rectangle;
5947 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005949 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005950 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005951 }
5952 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005953
5954 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005955 {
5956 bool restrictedMinFilter =
5957 target == TextureType::External || target == TextureType::Rectangle;
5958 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005960 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005961 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005962 }
5963 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005964
5965 case GL_TEXTURE_MAG_FILTER:
5966 if (!ValidateTextureMagFilterValue(context, params))
5967 {
5968 return false;
5969 }
5970 break;
5971
5972 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04005973 if (!context->getExtensions().textureUsage)
5974 {
5975 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5976 return false;
5977 }
5978
Jamie Madillbe849e42017-05-02 15:49:00 -04005979 switch (ConvertToGLenum(params[0]))
5980 {
5981 case GL_NONE:
5982 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
5983 break;
5984
5985 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005986 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 return false;
5988 }
5989 break;
5990
5991 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005992 {
5993 GLfloat paramValue = static_cast<GLfloat>(params[0]);
5994 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04005995 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005996 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005997 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005998 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
5999 }
6000 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006001
6002 case GL_TEXTURE_MIN_LOD:
6003 case GL_TEXTURE_MAX_LOD:
6004 // any value is permissible
6005 break;
6006
6007 case GL_TEXTURE_COMPARE_MODE:
6008 if (!ValidateTextureCompareModeValue(context, params))
6009 {
6010 return false;
6011 }
6012 break;
6013
6014 case GL_TEXTURE_COMPARE_FUNC:
6015 if (!ValidateTextureCompareFuncValue(context, params))
6016 {
6017 return false;
6018 }
6019 break;
6020
6021 case GL_TEXTURE_SWIZZLE_R:
6022 case GL_TEXTURE_SWIZZLE_G:
6023 case GL_TEXTURE_SWIZZLE_B:
6024 case GL_TEXTURE_SWIZZLE_A:
6025 switch (ConvertToGLenum(params[0]))
6026 {
6027 case GL_RED:
6028 case GL_GREEN:
6029 case GL_BLUE:
6030 case GL_ALPHA:
6031 case GL_ZERO:
6032 case GL_ONE:
6033 break;
6034
6035 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006036 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
6039 break;
6040
6041 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006042 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006044 context->handleError(InvalidValue() << "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006047 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006049 context->handleError(InvalidOperation()
6050 << "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 return false;
6052 }
Olli Etuahod310a432018-08-24 15:40:23 +03006053 if ((target == TextureType::_2DMultisample ||
6054 target == TextureType::_2DMultisampleArray) &&
6055 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006056 {
6057 context->handleError(InvalidOperation()
6058 << "Base level must be 0 for multisampled textures.");
6059 return false;
6060 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006061 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006062 {
6063 context->handleError(InvalidOperation()
6064 << "Base level must be 0 for rectangle textures.");
6065 return false;
6066 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006067 break;
6068
6069 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006070 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006071 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006072 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 return false;
6074 }
6075 break;
6076
6077 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6078 if (context->getClientVersion() < Version(3, 1))
6079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006080 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006081 return false;
6082 }
6083 switch (ConvertToGLenum(params[0]))
6084 {
6085 case GL_DEPTH_COMPONENT:
6086 case GL_STENCIL_INDEX:
6087 break;
6088
6089 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006090 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006091 return false;
6092 }
6093 break;
6094
6095 case GL_TEXTURE_SRGB_DECODE_EXT:
6096 if (!ValidateTextureSRGBDecodeValue(context, params))
6097 {
6098 return false;
6099 }
6100 break;
6101
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006102 case GL_GENERATE_MIPMAP:
6103 case GL_TEXTURE_CROP_RECT_OES:
6104 if (context->getClientMajorVersion() > 1)
6105 {
6106 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
6107 return false;
6108 }
6109 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006111 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006112 return false;
6113 }
6114
6115 return true;
6116}
6117
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006118template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLfloat *);
6119template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006120
Jamie Madill5b772312018-03-08 20:28:32 -05006121bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006122{
6123 if (index >= MAX_VERTEX_ATTRIBS)
6124 {
6125 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
6126 return false;
6127 }
6128
6129 return true;
6130}
6131
6132bool ValidateGetActiveUniformBlockivBase(Context *context,
6133 GLuint program,
6134 GLuint uniformBlockIndex,
6135 GLenum pname,
6136 GLsizei *length)
6137{
6138 if (length)
6139 {
6140 *length = 0;
6141 }
6142
6143 if (context->getClientMajorVersion() < 3)
6144 {
6145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6146 return false;
6147 }
6148
6149 Program *programObject = GetValidProgram(context, program);
6150 if (!programObject)
6151 {
6152 return false;
6153 }
6154
6155 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6156 {
6157 context->handleError(InvalidValue()
6158 << "uniformBlockIndex exceeds active uniform block count.");
6159 return false;
6160 }
6161
6162 switch (pname)
6163 {
6164 case GL_UNIFORM_BLOCK_BINDING:
6165 case GL_UNIFORM_BLOCK_DATA_SIZE:
6166 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6167 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6168 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6169 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6170 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6171 break;
6172
6173 default:
6174 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6175 return false;
6176 }
6177
6178 if (length)
6179 {
6180 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6181 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006182 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006183 programObject->getUniformBlockByIndex(uniformBlockIndex);
6184 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6185 }
6186 else
6187 {
6188 *length = 1;
6189 }
6190 }
6191
6192 return true;
6193}
6194
Jamie Madill9696d072017-08-26 23:19:57 -04006195template <typename ParamType>
6196bool ValidateSamplerParameterBase(Context *context,
6197 GLuint sampler,
6198 GLenum pname,
6199 GLsizei bufSize,
6200 ParamType *params)
6201{
6202 if (context->getClientMajorVersion() < 3)
6203 {
6204 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6205 return false;
6206 }
6207
6208 if (!context->isSampler(sampler))
6209 {
6210 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler);
6211 return false;
6212 }
6213
6214 const GLsizei minBufSize = 1;
6215 if (bufSize >= 0 && bufSize < minBufSize)
6216 {
6217 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
6218 return false;
6219 }
6220
6221 switch (pname)
6222 {
6223 case GL_TEXTURE_WRAP_S:
6224 case GL_TEXTURE_WRAP_T:
6225 case GL_TEXTURE_WRAP_R:
6226 if (!ValidateTextureWrapModeValue(context, params, false))
6227 {
6228 return false;
6229 }
6230 break;
6231
6232 case GL_TEXTURE_MIN_FILTER:
6233 if (!ValidateTextureMinFilterValue(context, params, false))
6234 {
6235 return false;
6236 }
6237 break;
6238
6239 case GL_TEXTURE_MAG_FILTER:
6240 if (!ValidateTextureMagFilterValue(context, params))
6241 {
6242 return false;
6243 }
6244 break;
6245
6246 case GL_TEXTURE_MIN_LOD:
6247 case GL_TEXTURE_MAX_LOD:
6248 // any value is permissible
6249 break;
6250
6251 case GL_TEXTURE_COMPARE_MODE:
6252 if (!ValidateTextureCompareModeValue(context, params))
6253 {
6254 return false;
6255 }
6256 break;
6257
6258 case GL_TEXTURE_COMPARE_FUNC:
6259 if (!ValidateTextureCompareFuncValue(context, params))
6260 {
6261 return false;
6262 }
6263 break;
6264
6265 case GL_TEXTURE_SRGB_DECODE_EXT:
6266 if (!ValidateTextureSRGBDecodeValue(context, params))
6267 {
6268 return false;
6269 }
6270 break;
6271
Luc Ferron1b1a8642018-01-23 15:12:01 -05006272 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6273 {
6274 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6275 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6276 {
6277 return false;
6278 }
6279 }
6280 break;
6281
Jamie Madill9696d072017-08-26 23:19:57 -04006282 default:
6283 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6284 return false;
6285 }
6286
6287 return true;
6288}
6289
6290template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLfloat *);
6291template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLint *);
6292
6293bool ValidateGetSamplerParameterBase(Context *context,
6294 GLuint sampler,
6295 GLenum pname,
6296 GLsizei *length)
6297{
6298 if (length)
6299 {
6300 *length = 0;
6301 }
6302
6303 if (context->getClientMajorVersion() < 3)
6304 {
6305 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6306 return false;
6307 }
6308
6309 if (!context->isSampler(sampler))
6310 {
6311 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler);
6312 return false;
6313 }
6314
6315 switch (pname)
6316 {
6317 case GL_TEXTURE_WRAP_S:
6318 case GL_TEXTURE_WRAP_T:
6319 case GL_TEXTURE_WRAP_R:
6320 case GL_TEXTURE_MIN_FILTER:
6321 case GL_TEXTURE_MAG_FILTER:
6322 case GL_TEXTURE_MIN_LOD:
6323 case GL_TEXTURE_MAX_LOD:
6324 case GL_TEXTURE_COMPARE_MODE:
6325 case GL_TEXTURE_COMPARE_FUNC:
6326 break;
6327
Luc Ferron1b1a8642018-01-23 15:12:01 -05006328 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6329 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6330 {
6331 return false;
6332 }
6333 break;
6334
Jamie Madill9696d072017-08-26 23:19:57 -04006335 case GL_TEXTURE_SRGB_DECODE_EXT:
6336 if (!context->getExtensions().textureSRGBDecode)
6337 {
6338 context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled.");
6339 return false;
6340 }
6341 break;
6342
6343 default:
6344 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6345 return false;
6346 }
6347
6348 if (length)
6349 {
6350 *length = 1;
6351 }
6352 return true;
6353}
6354
6355bool ValidateGetInternalFormativBase(Context *context,
6356 GLenum target,
6357 GLenum internalformat,
6358 GLenum pname,
6359 GLsizei bufSize,
6360 GLsizei *numParams)
6361{
6362 if (numParams)
6363 {
6364 *numParams = 0;
6365 }
6366
6367 if (context->getClientMajorVersion() < 3)
6368 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08006369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006370 return false;
6371 }
6372
6373 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006374 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006375 {
6376 context->handleError(InvalidEnum() << "Internal format is not renderable.");
6377 return false;
6378 }
6379
6380 switch (target)
6381 {
6382 case GL_RENDERBUFFER:
6383 break;
6384
6385 case GL_TEXTURE_2D_MULTISAMPLE:
6386 if (context->getClientVersion() < ES_3_1)
6387 {
Olli Etuahod310a432018-08-24 15:40:23 +03006388 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureTargetRequiresES31);
Jamie Madill9696d072017-08-26 23:19:57 -04006389 return false;
6390 }
6391 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006392 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6393 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
6396 return false;
6397 }
6398 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006399 default:
6400 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTarget);
6401 return false;
6402 }
6403
6404 if (bufSize < 0)
6405 {
6406 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
6407 return false;
6408 }
6409
6410 GLsizei maxWriteParams = 0;
6411 switch (pname)
6412 {
6413 case GL_NUM_SAMPLE_COUNTS:
6414 maxWriteParams = 1;
6415 break;
6416
6417 case GL_SAMPLES:
6418 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6419 break;
6420
6421 default:
6422 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6423 return false;
6424 }
6425
6426 if (numParams)
6427 {
6428 // glGetInternalFormativ will not overflow bufSize
6429 *numParams = std::min(bufSize, maxWriteParams);
6430 }
6431
6432 return true;
6433}
6434
Jamie Madille98b1b52018-03-08 09:47:23 -05006435bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6436{
Jamie Madill427064d2018-04-13 16:20:34 -04006437 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006438 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03006439 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006440 return false;
6441 }
6442 return true;
6443}
6444
Lingfeng Yang038dd532018-03-29 17:31:52 -07006445bool ValidateMultitextureUnit(Context *context, GLenum texture)
6446{
6447 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6448 {
6449 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMultitextureUnit);
6450 return false;
6451 }
6452 return true;
6453}
6454
Olli Etuahod310a432018-08-24 15:40:23 +03006455bool ValidateTexStorageMultisample(Context *context,
6456 TextureType target,
6457 GLsizei samples,
6458 GLint internalFormat,
6459 GLsizei width,
6460 GLsizei height)
6461{
6462 const Caps &caps = context->getCaps();
6463 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6464 static_cast<GLuint>(height) > caps.max2DTextureSize)
6465 {
6466 ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureWidthOrHeightOutOfRange);
6467 return false;
6468 }
6469
6470 if (samples == 0)
6471 {
6472 ANGLE_VALIDATION_ERR(context, InvalidValue(), SamplesZero);
6473 return false;
6474 }
6475
6476 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6477 if (!formatCaps.textureAttachment)
6478 {
6479 ANGLE_VALIDATION_ERR(context, InvalidEnum(), RenderableInternalFormat);
6480 return false;
6481 }
6482
6483 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6484 // is one of the unsized base internalformats listed in table 8.11.
6485 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6486 if (formatInfo.internalFormat == GL_NONE)
6487 {
6488 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnsizedInternalFormatUnsupported);
6489 return false;
6490 }
6491
6492 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6493 {
6494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), SamplesOutOfRange);
6495 return false;
6496 }
6497
6498 Texture *texture = context->getTargetTexture(target);
6499 if (!texture || texture->id() == 0)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ZeroBoundToTarget);
6502 return false;
6503 }
6504
6505 if (texture->getImmutableFormat())
6506 {
6507 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ImmutableTextureBound);
6508 return false;
6509 }
6510 return true;
6511}
6512
Jamie Madillc29968b2016-01-20 11:17:23 -05006513} // namespace gl