blob: 9625028c1ee42d3f5a8480751ad0236c10d51958 [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:
Olli Etuahof2ed2992018-10-04 13:54:42 +030059 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
60 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
61 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
62 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Luc Ferron9dbaeba2018-02-01 07:26:59 -050063 return true;
jchen10a99ed552017-09-22 08:10:32 +080064
Luc Ferron9dbaeba2018-02-01 07:26:59 -050065 default:
66 return false;
67 }
68}
69bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
70{
71 // Compressed sub textures have additional formats that requires exact size.
72 // ES 3.1, Section 8.7, Page 171
73 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
74 IsETC2EACFormat(internalFormat);
75}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030076
77bool DifferenceCanOverflow(GLint a, GLint b)
78{
79 CheckedNumeric<GLint> checkedA(a);
80 checkedA -= b;
81 // Use negation to make sure that the difference can't overflow regardless of the order.
82 checkedA = -checkedA;
83 return !checkedA.IsValid();
84}
85
Jamie Madill16e28fd2018-09-12 11:03:05 -040086bool ValidateDrawAttribsImpl(Context *context, GLint primcount, GLint maxVertex)
Jamie Madill1ca74672015-07-21 15:14:11 -040087{
Jamie Madill51af38b2018-04-15 08:50:56 -040088 // If we're drawing zero vertices, we have enough data.
Jamie Madill2da53562018-08-01 11:34:47 -040089 ASSERT(primcount > 0);
Jamie Madill51af38b2018-04-15 08:50:56 -040090
Jamie Madill88602e62018-08-08 12:49:30 -040091 // An overflow can happen when adding the offset. Check against a special constant.
92 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
93 VertexAttribute::kIntegerOverflow ||
94 context->getStateCache().getInstancedVertexElementLimit() ==
95 VertexAttribute::kIntegerOverflow)
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040096 {
97 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
98 return false;
99 }
100
101 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
102 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
103 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientVertexBufferSize);
104 return false;
Jamie Madill1ca74672015-07-21 15:14:11 -0400105}
106
Jamie Madill16e28fd2018-09-12 11:03:05 -0400107ANGLE_INLINE bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex)
108{
109 if (maxVertex <= context->getStateCache().getNonInstancedVertexElementLimit() &&
110 (primcount - 1) <= context->getStateCache().getInstancedVertexElementLimit())
111 {
112 return true;
113 }
114 else
115 {
116 return ValidateDrawAttribsImpl(context, primcount, maxVertex);
117 }
118}
119
Jamie Madill5b772312018-03-08 20:28:32 -0500120bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -0400121{
122 switch (type)
123 {
124 // Types referenced in Table 3.4 of the ES 2.0.25 spec
125 case GL_UNSIGNED_BYTE:
126 case GL_UNSIGNED_SHORT_4_4_4_4:
127 case GL_UNSIGNED_SHORT_5_5_5_1:
128 case GL_UNSIGNED_SHORT_5_6_5:
129 return context->getClientVersion() >= ES_2_0;
130
131 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
132 case GL_BYTE:
133 case GL_INT:
134 case GL_SHORT:
135 case GL_UNSIGNED_INT:
136 case GL_UNSIGNED_INT_10F_11F_11F_REV:
137 case GL_UNSIGNED_INT_24_8:
138 case GL_UNSIGNED_INT_2_10_10_10_REV:
139 case GL_UNSIGNED_INT_5_9_9_9_REV:
140 case GL_UNSIGNED_SHORT:
141 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
142 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
143 return context->getClientVersion() >= ES_3_0;
144
145 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400146 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
147 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400148
149 case GL_HALF_FLOAT:
150 return context->getClientVersion() >= ES_3_0 ||
151 context->getExtensions().textureHalfFloat;
152
153 case GL_HALF_FLOAT_OES:
154 return context->getExtensions().colorBufferHalfFloat;
155
156 default:
157 return false;
158 }
159}
160
Jamie Madill5b772312018-03-08 20:28:32 -0500161bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400162{
163 switch (format)
164 {
165 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
166 case GL_RGBA:
167 case GL_RGB:
168 case GL_ALPHA:
169 return context->getClientVersion() >= ES_2_0;
170
171 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
172 case GL_RG:
173 case GL_RED:
174 case GL_RGBA_INTEGER:
175 case GL_RGB_INTEGER:
176 case GL_RG_INTEGER:
177 case GL_RED_INTEGER:
178 return context->getClientVersion() >= ES_3_0;
179
180 case GL_SRGB_ALPHA_EXT:
181 case GL_SRGB_EXT:
182 return context->getExtensions().sRGB;
183
184 case GL_BGRA_EXT:
185 return context->getExtensions().readFormatBGRA;
186
187 default:
188 return false;
189 }
190}
191
Jamie Madill5b772312018-03-08 20:28:32 -0500192bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400193 GLenum framebufferComponentType,
194 GLenum format,
195 GLenum type)
196{
197 switch (framebufferComponentType)
198 {
199 case GL_UNSIGNED_NORMALIZED:
200 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
201 // ReadPixels with BGRA even if the extension is not present
202 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
203 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
204 type == GL_UNSIGNED_BYTE);
205
206 case GL_SIGNED_NORMALIZED:
207 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
208
209 case GL_INT:
210 return (format == GL_RGBA_INTEGER && type == GL_INT);
211
212 case GL_UNSIGNED_INT:
213 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
214
215 case GL_FLOAT:
216 return (format == GL_RGBA && type == GL_FLOAT);
217
218 default:
219 UNREACHABLE();
220 return false;
221 }
222}
223
Geoff Langc1984ed2016-10-07 12:41:00 -0400224template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400225bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400226{
227 switch (ConvertToGLenum(params[0]))
228 {
229 case GL_CLAMP_TO_EDGE:
230 break;
231
232 case GL_REPEAT:
233 case GL_MIRRORED_REPEAT:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400234 if (restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400235 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400236 // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
Brandon Jonesafa75152017-07-21 13:11:29 -0700237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400238 return false;
239 }
240 break;
241
242 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700243 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureWrap);
Geoff Langc1984ed2016-10-07 12:41:00 -0400244 return false;
245 }
246
247 return true;
248}
249
250template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400251bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400252{
253 switch (ConvertToGLenum(params[0]))
254 {
255 case GL_NEAREST:
256 case GL_LINEAR:
257 break;
258
259 case GL_NEAREST_MIPMAP_NEAREST:
260 case GL_LINEAR_MIPMAP_NEAREST:
261 case GL_NEAREST_MIPMAP_LINEAR:
262 case GL_LINEAR_MIPMAP_LINEAR:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400263 if (restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400264 {
265 // OES_EGL_image_external specifies this error.
Brandon Jonesafa75152017-07-21 13:11:29 -0700266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400267 return false;
268 }
269 break;
270
271 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700272 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400273 return false;
274 }
275
276 return true;
277}
278
279template <typename ParamType>
280bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
281{
282 switch (ConvertToGLenum(params[0]))
283 {
284 case GL_NEAREST:
285 case GL_LINEAR:
286 break;
287
288 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700289 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400290 return false;
291 }
292
293 return true;
294}
295
296template <typename ParamType>
297bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
298{
299 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
300 switch (ConvertToGLenum(params[0]))
301 {
302 case GL_NONE:
303 case GL_COMPARE_REF_TO_TEXTURE:
304 break;
305
306 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700307 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400308 return false;
309 }
310
311 return true;
312}
313
314template <typename ParamType>
315bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
316{
317 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
318 switch (ConvertToGLenum(params[0]))
319 {
320 case GL_LEQUAL:
321 case GL_GEQUAL:
322 case GL_LESS:
323 case GL_GREATER:
324 case GL_EQUAL:
325 case GL_NOTEQUAL:
326 case GL_ALWAYS:
327 case GL_NEVER:
328 break;
329
330 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400332 return false;
333 }
334
335 return true;
336}
337
338template <typename ParamType>
Geoff Lang81c6b572016-10-19 14:07:52 -0700339bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
340{
341 if (!context->getExtensions().textureSRGBDecode)
342 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700343 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Geoff Lang81c6b572016-10-19 14:07:52 -0700344 return false;
345 }
346
347 switch (ConvertToGLenum(params[0]))
348 {
349 case GL_DECODE_EXT:
350 case GL_SKIP_DECODE_EXT:
351 break;
352
353 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700354 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
Geoff Lang81c6b572016-10-19 14:07:52 -0700355 return false;
356 }
357
358 return true;
359}
360
Luc Ferron1b1a8642018-01-23 15:12:01 -0500361bool ValidateTextureMaxAnisotropyExtensionEnabled(Context *context)
362{
363 if (!context->getExtensions().textureFilterAnisotropic)
364 {
365 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
366 return false;
367 }
368
369 return true;
370}
371
372bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
373{
374 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
375 {
376 return false;
377 }
378
379 GLfloat largest = context->getExtensions().maxTextureAnisotropy;
380
381 if (paramValue < 1 || paramValue > largest)
382 {
383 ANGLE_VALIDATION_ERR(context, InvalidValue(), OutsideOfBounds);
384 return false;
385 }
386
387 return true;
388}
389
Jamie Madill5b772312018-03-08 20:28:32 -0500390bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
Geoff Lange0cff192017-05-30 13:04:56 -0400391{
Jamie Madill785e8a02018-10-04 17:42:00 -0400392 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lange0cff192017-05-30 13:04:56 -0400393 const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
394
Jamie Madille7d80f32018-08-08 15:49:23 -0400395 return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
396 framebuffer->getDrawBufferTypeMask().to_ulong(),
397 program->getActiveOutputVariables().to_ulong(),
398 framebuffer->getDrawBufferMask().to_ulong());
Geoff Lange0cff192017-05-30 13:04:56 -0400399}
400
Jamie Madill5b772312018-03-08 20:28:32 -0500401bool ValidateVertexShaderAttributeTypeMatch(Context *context)
Geoff Lang9ab5b822017-05-30 16:19:23 -0400402{
Lingfeng Yang038dd532018-03-29 17:31:52 -0700403 const auto &glState = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -0400404 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400405 const VertexArray *vao = context->getGLState().getVertexArray();
406
Brandon Jonesc405ae72017-12-06 14:15:03 -0800407 unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
408 unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
409 unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
410
411 vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
412 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
413 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
414
Jamie Madille7d80f32018-08-08 15:49:23 -0400415 return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
416 vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
417 0xFFFF);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400418}
419
Jamie Madill493f9572018-05-24 19:52:15 -0400420bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
421 PrimitiveMode geometryShaderInputPrimitiveType)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800422{
423 // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
Jamie Madill493f9572018-05-24 19:52:15 -0400424 switch (drawMode)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800425 {
Jamie Madill493f9572018-05-24 19:52:15 -0400426 case PrimitiveMode::Points:
427 return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
428 case PrimitiveMode::Lines:
429 case PrimitiveMode::LineStrip:
430 case PrimitiveMode::LineLoop:
431 return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
432 case PrimitiveMode::LinesAdjacency:
433 case PrimitiveMode::LineStripAdjacency:
434 return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
435 case PrimitiveMode::Triangles:
436 case PrimitiveMode::TriangleFan:
437 case PrimitiveMode::TriangleStrip:
438 return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
439 case PrimitiveMode::TrianglesAdjacency:
440 case PrimitiveMode::TriangleStripAdjacency:
441 return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
Jiawei Shaofccebff2018-03-08 13:51:02 +0800442 default:
443 UNREACHABLE();
444 return false;
445 }
446}
447
Lingfeng Yangf97641c2018-06-21 19:22:45 -0700448// GLES1 texture parameters are a small subset of the others
449bool IsValidGLES1TextureParameter(GLenum pname)
450{
451 switch (pname)
452 {
453 case GL_TEXTURE_MAG_FILTER:
454 case GL_TEXTURE_MIN_FILTER:
455 case GL_TEXTURE_WRAP_S:
456 case GL_TEXTURE_WRAP_T:
457 case GL_TEXTURE_WRAP_R:
458 case GL_GENERATE_MIPMAP:
459 case GL_TEXTURE_CROP_RECT_OES:
460 return true;
461 default:
462 return false;
463 }
464}
Geoff Langf41a7152016-09-19 15:11:17 -0400465} // anonymous namespace
466
Brandon Jonesd1049182018-03-28 10:02:20 -0700467void SetRobustLengthParam(GLsizei *length, GLsizei value)
468{
469 if (length)
470 {
471 *length = value;
472 }
473}
474
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500475bool IsETC2EACFormat(const GLenum format)
476{
477 // ES 3.1, Table 8.19
478 switch (format)
479 {
480 case GL_COMPRESSED_R11_EAC:
481 case GL_COMPRESSED_SIGNED_R11_EAC:
482 case GL_COMPRESSED_RG11_EAC:
483 case GL_COMPRESSED_SIGNED_RG11_EAC:
484 case GL_COMPRESSED_RGB8_ETC2:
485 case GL_COMPRESSED_SRGB8_ETC2:
486 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
487 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
488 case GL_COMPRESSED_RGBA8_ETC2_EAC:
489 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
490 return true;
491
492 default:
493 return false;
494 }
495}
496
Jamie Madill5b772312018-03-08 20:28:32 -0500497bool ValidTextureTarget(const Context *context, TextureType type)
Jamie Madill35d15012013-10-07 10:46:37 -0400498{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800499 switch (type)
Jamie Madill35d15012013-10-07 10:46:37 -0400500 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800501 case TextureType::_2D:
502 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800503 return true;
Jamie Madill35d15012013-10-07 10:46:37 -0400504
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800505 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400506 return context->getExtensions().textureRectangle;
507
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800508 case TextureType::_3D:
509 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800510 return (context->getClientMajorVersion() >= 3);
Jamie Madilld7460c72014-01-21 16:38:14 -0500511
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800512 case TextureType::_2DMultisample:
He Yunchaoced53ae2016-11-29 15:00:51 +0800513 return (context->getClientVersion() >= Version(3, 1));
Olli Etuahod310a432018-08-24 15:40:23 +0300514 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300515 return context->getExtensions().textureStorageMultisample2DArray;
Geoff Lang3b573612016-10-31 14:08:10 -0400516
He Yunchaoced53ae2016-11-29 15:00:51 +0800517 default:
518 return false;
Jamie Madilld7460c72014-01-21 16:38:14 -0500519 }
Jamie Madill35d15012013-10-07 10:46:37 -0400520}
521
Jamie Madill5b772312018-03-08 20:28:32 -0500522bool ValidTexture2DTarget(const Context *context, TextureType type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500523{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800524 switch (type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500525 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800526 case TextureType::_2D:
527 case TextureType::CubeMap:
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500528 return true;
529
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800530 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400531 return context->getExtensions().textureRectangle;
532
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500533 default:
534 return false;
535 }
536}
537
Jamie Madill5b772312018-03-08 20:28:32 -0500538bool ValidTexture3DTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500539{
540 switch (target)
541 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800542 case TextureType::_3D:
543 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +0300544 return (context->getClientMajorVersion() >= 3);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500545
546 default:
547 return false;
548 }
549}
550
Ian Ewellbda75592016-04-18 17:25:54 -0400551// Most texture GL calls are not compatible with external textures, so we have a separate validation
552// function for use in the GL calls that do
Jamie Madill5b772312018-03-08 20:28:32 -0500553bool ValidTextureExternalTarget(const Context *context, TextureType target)
Ian Ewellbda75592016-04-18 17:25:54 -0400554{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800555 return (target == TextureType::External) &&
Ian Ewellbda75592016-04-18 17:25:54 -0400556 (context->getExtensions().eglImageExternal ||
557 context->getExtensions().eglStreamConsumerExternal);
558}
559
Shannon Woods4dfed832014-03-17 20:03:39 -0400560// This function differs from ValidTextureTarget in that the target must be
561// usable as the destination of a 2D operation-- so a cube face is valid, but
562// GL_TEXTURE_CUBE_MAP is not.
Jamie Madill560a8d82014-05-21 13:06:20 -0400563// Note: duplicate of IsInternalTextureTarget
Jamie Madill5b772312018-03-08 20:28:32 -0500564bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
Shannon Woods4dfed832014-03-17 20:03:39 -0400565{
566 switch (target)
567 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800568 case TextureTarget::_2D:
569 case TextureTarget::CubeMapNegativeX:
570 case TextureTarget::CubeMapNegativeY:
571 case TextureTarget::CubeMapNegativeZ:
572 case TextureTarget::CubeMapPositiveX:
573 case TextureTarget::CubeMapPositiveY:
574 case TextureTarget::CubeMapPositiveZ:
He Yunchaoced53ae2016-11-29 15:00:51 +0800575 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800576 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400577 return context->getExtensions().textureRectangle;
He Yunchaoced53ae2016-11-29 15:00:51 +0800578 default:
579 return false;
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500580 }
581}
582
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800583bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400584 PrimitiveMode transformFeedbackPrimitiveMode,
585 PrimitiveMode renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800586{
587 ASSERT(context);
588
589 if (!context->getExtensions().geometryShader)
590 {
591 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
592 // that does not match the current transform feedback object's draw mode (if transform
593 // feedback is active), (3.0.2, section 2.14, pg 86)
594 return transformFeedbackPrimitiveMode == renderPrimitiveMode;
595 }
596
597 // [GL_EXT_geometry_shader] Table 12.1gs
Jamie Madill493f9572018-05-24 19:52:15 -0400598 switch (renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800599 {
Jamie Madill493f9572018-05-24 19:52:15 -0400600 case PrimitiveMode::Points:
601 return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
602 case PrimitiveMode::Lines:
603 case PrimitiveMode::LineStrip:
604 case PrimitiveMode::LineLoop:
605 return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
606 case PrimitiveMode::Triangles:
607 case PrimitiveMode::TriangleFan:
608 case PrimitiveMode::TriangleStrip:
609 return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800610 default:
611 UNREACHABLE();
612 return false;
613 }
614}
615
Jamie Madill5b772312018-03-08 20:28:32 -0500616bool ValidateDrawElementsInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400617 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400618 GLsizei count,
619 GLenum type,
620 const GLvoid *indices,
621 GLsizei primcount)
622{
623 if (primcount < 0)
624 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700625 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400626 return false;
627 }
628
629 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount))
630 {
631 return false;
632 }
633
Jamie Madill9fdaa492018-02-16 10:52:11 -0500634 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400635}
636
637bool ValidateDrawArraysInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400638 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400639 GLint first,
640 GLsizei count,
641 GLsizei primcount)
642{
643 if (primcount < 0)
644 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700645 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400646 return false;
647 }
648
649 if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
650 {
651 return false;
652 }
653
Jamie Madill9fdaa492018-02-16 10:52:11 -0500654 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400655}
656
Jamie Madill5b772312018-03-08 20:28:32 -0500657bool ValidateDrawInstancedANGLE(Context *context)
Jamie Madillbe849e42017-05-02 15:49:00 -0400658{
659 // Verify there is at least one active attribute with a divisor of zero
660 const State &state = context->getGLState();
661
Jamie Madill785e8a02018-10-04 17:42:00 -0400662 Program *program = state.getLinkedProgram(context);
Jamie Madillbe849e42017-05-02 15:49:00 -0400663
664 const auto &attribs = state.getVertexArray()->getVertexAttributes();
665 const auto &bindings = state.getVertexArray()->getVertexBindings();
666 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
667 {
668 const VertexAttribute &attrib = attribs[attributeIndex];
669 const VertexBinding &binding = bindings[attrib.bindingIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +0300670 if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400671 {
672 return true;
673 }
674 }
675
Brandon Jonesafa75152017-07-21 13:11:29 -0700676 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoZeroDivisor);
Jamie Madillbe849e42017-05-02 15:49:00 -0400677 return false;
678}
679
Jamie Madill5b772312018-03-08 20:28:32 -0500680bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500681{
682 switch (target)
683 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800684 case TextureType::_3D:
685 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800686 return true;
687 default:
688 return false;
Shannon Woods4dfed832014-03-17 20:03:39 -0400689 }
690}
691
Jamie Madill5b772312018-03-08 20:28:32 -0500692bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
He Yunchao11b038b2016-11-22 21:24:04 +0800693{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800694 switch (type)
He Yunchao11b038b2016-11-22 21:24:04 +0800695 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800696 case TextureType::_2D:
697 case TextureType::_2DArray:
698 case TextureType::_2DMultisample:
699 case TextureType::CubeMap:
700 case TextureType::_3D:
He Yunchao11b038b2016-11-22 21:24:04 +0800701 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800702 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400703 return context->getExtensions().textureRectangle;
Olli Etuahod310a432018-08-24 15:40:23 +0300704 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300705 return context->getExtensions().textureStorageMultisample2DArray;
He Yunchao11b038b2016-11-22 21:24:04 +0800706 default:
707 return false;
708 }
709}
710
Jamie Madill5b772312018-03-08 20:28:32 -0500711bool ValidFramebufferTarget(const Context *context, GLenum target)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500712{
He Yunchaoced53ae2016-11-29 15:00:51 +0800713 static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
714 GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
Geoff Langd4475812015-03-18 10:53:05 -0400715 "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500716
717 switch (target)
718 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800719 case GL_FRAMEBUFFER:
720 return true;
Geoff Lange8afa902017-09-27 15:00:43 -0400721
He Yunchaoced53ae2016-11-29 15:00:51 +0800722 case GL_READ_FRAMEBUFFER:
He Yunchaoced53ae2016-11-29 15:00:51 +0800723 case GL_DRAW_FRAMEBUFFER:
Geoff Lange8afa902017-09-27 15:00:43 -0400724 return (context->getExtensions().framebufferBlit ||
725 context->getClientMajorVersion() >= 3);
726
He Yunchaoced53ae2016-11-29 15:00:51 +0800727 default:
728 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500729 }
730}
731
Jamie Madill5b772312018-03-08 20:28:32 -0500732bool ValidMipLevel(const Context *context, TextureType type, GLint level)
Geoff Langce635692013-09-24 13:56:32 -0400733{
Jamie Madillc29968b2016-01-20 11:17:23 -0500734 const auto &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -0400735 size_t maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800736 switch (type)
Geoff Langce635692013-09-24 13:56:32 -0400737 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800738 case TextureType::_2D:
739 case TextureType::_2DArray:
740 case TextureType::_2DMultisample:
Olli Etuahod310a432018-08-24 15:40:23 +0300741 case TextureType::_2DMultisampleArray:
742 // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
743 // level-of-detail" for multisample textures should be. Could maybe make it zero.
Jamie Madillc29968b2016-01-20 11:17:23 -0500744 maxDimension = caps.max2DTextureSize;
745 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800746 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800747 maxDimension = caps.maxCubeMapTextureSize;
748 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800749 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400750 return level == 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800751 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800752 maxDimension = caps.max3DTextureSize;
753 break;
He Yunchaoced53ae2016-11-29 15:00:51 +0800754 default:
755 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400756 }
757
Jamie Madill43da7c42018-08-01 11:34:49 -0400758 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400759}
760
Jamie Madill5b772312018-03-08 20:28:32 -0500761bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800762 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700763 GLint level,
764 GLsizei width,
765 GLsizei height,
766 GLsizei depth,
767 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400768{
Brandon Jones6cad5662017-06-14 13:25:13 -0700769 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400770 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700771 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400772 return false;
773 }
Austin Kinross08528e12015-10-07 16:24:40 -0700774 // TexSubImage parameters can be NPOT without textureNPOT extension,
775 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500776 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500777 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500778 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400779 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400780 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700781 ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400782 return false;
783 }
784
785 if (!ValidMipLevel(context, target, level))
786 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700787 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400788 return false;
789 }
790
791 return true;
792}
793
Geoff Lang966c9402017-04-18 12:38:27 -0400794bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
795{
796 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
797 (size % blockSize == 0);
798}
799
Jamie Madill5b772312018-03-08 20:28:32 -0500800bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500801 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400802 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500803 GLsizei width,
804 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400805{
Jamie Madill43da7c42018-08-01 11:34:49 -0400806 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400807 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400808 {
809 return false;
810 }
811
Geoff Lang966c9402017-04-18 12:38:27 -0400812 if (width < 0 || height < 0)
813 {
814 return false;
815 }
816
817 if (CompressedTextureFormatRequiresExactSize(internalFormat))
818 {
819 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
820 // block size for level 0 but WebGL disallows this.
821 bool smallerThanBlockSizeAllowed =
822 level > 0 || !context->getExtensions().webglCompatibility;
823
824 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
825 smallerThanBlockSizeAllowed) ||
826 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
827 smallerThanBlockSizeAllowed))
828 {
829 return false;
830 }
831 }
832
833 return true;
834}
835
Jamie Madill5b772312018-03-08 20:28:32 -0500836bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400837 GLenum internalFormat,
838 GLint xoffset,
839 GLint yoffset,
840 GLsizei width,
841 GLsizei height,
842 size_t textureWidth,
843 size_t textureHeight)
844{
Jamie Madill43da7c42018-08-01 11:34:49 -0400845 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400846 if (!formatInfo.compressed)
847 {
848 return false;
849 }
850
Geoff Lang44ff5a72017-02-03 15:15:43 -0500851 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400852 {
853 return false;
854 }
855
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500856 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400857 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500858 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400859 yoffset % formatInfo.compressedBlockHeight != 0)
860 {
861 return false;
862 }
863
864 // Allowed to either have data that is a multiple of block size or is smaller than the block
865 // size but fills the entire mip
866 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
867 static_cast<size_t>(width) == textureWidth &&
868 static_cast<size_t>(height) == textureHeight;
869 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
870 (height % formatInfo.compressedBlockHeight) == 0;
871 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400872 {
873 return false;
874 }
875 }
876
Geoff Langd4f180b2013-09-24 13:57:44 -0400877 return true;
878}
879
Jamie Madill5b772312018-03-08 20:28:32 -0500880bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800881 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400882 GLsizei width,
883 GLsizei height,
884 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400885 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400886 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400887 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400888 GLsizei imageSize)
889{
Jamie Madill43da7c42018-08-01 11:34:49 -0400890 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400891 if (pixelUnpackBuffer == nullptr && imageSize < 0)
892 {
893 // Checks are not required
894 return true;
895 }
896
897 // ...the data would be unpacked from the buffer object such that the memory reads required
898 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400899 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400900 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400901 const Extents size(width, height, depth);
Geoff Langff5b2d52016-09-07 11:32:23 -0400902 const auto &unpack = context->getGLState().getUnpackState();
903
Jamie Madill7f232932018-09-12 11:03:06 -0400904 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
905 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400906 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400907 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400908 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400909 return false;
910 }
911
Geoff Langff5b2d52016-09-07 11:32:23 -0400912 if (pixelUnpackBuffer)
913 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400914 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400915 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
916 checkedEndByte += checkedOffset;
917
918 if (!checkedEndByte.IsValid() ||
919 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
920 {
921 // Overflow past the end of the buffer
Jamie Madillca2ff382018-07-11 09:01:17 -0400922 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400923 return false;
924 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800925 if (context->getExtensions().webglCompatibility &&
926 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
927 {
928 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
929 PixelUnpackBufferBoundForTransformFeedback);
930 return false;
931 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400932 }
933 else
934 {
935 ASSERT(imageSize >= 0);
936 if (pixels == nullptr && imageSize != 0)
937 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500938 context->handleError(InvalidOperation()
939 << "imageSize must be 0 if no texture data is provided.");
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400940 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400941 }
942
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400943 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500945 context->handleError(InvalidOperation() << "imageSize must be at least " << endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400946 return false;
947 }
948 }
949
950 return true;
951}
952
Corentin Wallezad3ae902018-03-09 13:40:42 -0500953bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500954{
Geoff Lang37dde692014-01-31 16:34:54 -0500955 switch (queryType)
956 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500957 case QueryType::AnySamples:
958 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400959 return context->getClientMajorVersion() >= 3 ||
960 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500961 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800962 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500963 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800964 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500965 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800966 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500967 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800968 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800969 default:
970 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500971 }
972}
973
Jamie Madill5b772312018-03-08 20:28:32 -0500974bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400975 GLenum type,
976 GLboolean normalized,
977 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400978 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400979 bool pureInteger)
980{
981 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -0400982 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
983 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
984 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
985 // parameter exceeds 255.
986 constexpr GLsizei kMaxWebGLStride = 255;
987 if (stride > kMaxWebGLStride)
988 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500989 context->handleError(InvalidValue()
990 << "Stride is over the maximum stride allowed by WebGL.");
Geoff Lang2d62ab72017-03-23 16:54:40 -0400991 return false;
992 }
993
994 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
995 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
996 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
997 // or an INVALID_OPERATION error is generated.
Frank Henigmand633b152018-10-04 23:34:31 -0400998 angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
999 size_t typeSize = GetVertexFormatSize(internalType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001000
1001 ASSERT(isPow2(typeSize) && typeSize > 0);
1002 size_t sizeMask = (typeSize - 1);
1003 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1004 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001005 ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001006 return false;
1007 }
1008
1009 if ((stride & sizeMask) != 0)
1010 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001011 ANGLE_VALIDATION_ERR(context, InvalidOperation(), StrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001012 return false;
1013 }
1014
1015 return true;
1016}
1017
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001018Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001019{
He Yunchaoced53ae2016-11-29 15:00:51 +08001020 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1021 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1022 // or program object and INVALID_OPERATION if the provided name identifies an object
1023 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001024
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001025 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001026
1027 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001028 {
Dian Xiang769769a2015-09-09 15:20:08 -07001029 if (context->getShader(id))
1030 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001031 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001032 }
1033 else
1034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001035 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001036 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001037 }
Dian Xiang769769a2015-09-09 15:20:08 -07001038
1039 return validProgram;
1040}
1041
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001042Program *GetValidProgram(Context *context, GLuint id)
1043{
1044 Program *program = GetValidProgramNoResolve(context, id);
1045 if (program)
1046 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001047 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001048 }
1049 return program;
1050}
1051
Jamie Madill5b772312018-03-08 20:28:32 -05001052Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001053{
1054 // See ValidProgram for spec details.
1055
1056 Shader *validShader = context->getShader(id);
1057
1058 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001059 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001060 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001061 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001062 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001063 }
1064 else
1065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001066 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001067 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001068 }
Dian Xiang769769a2015-09-09 15:20:08 -07001069
1070 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001071}
1072
Jamie Madill43da7c42018-08-01 11:34:49 -04001073bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001074{
Geoff Langfa125c92017-10-24 13:01:46 -04001075 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001076 {
Geoff Langfa125c92017-10-24 13:01:46 -04001077 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1078 {
1079 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
1080 return false;
1081 }
Jamie Madillb4472272014-07-03 10:38:55 -04001082
Geoff Langfa125c92017-10-24 13:01:46 -04001083 // Color attachment 0 is validated below because it is always valid
1084 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001085 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001086 {
Geoff Langfa125c92017-10-24 13:01:46 -04001087 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001088 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001089 }
1090 }
1091 else
1092 {
1093 switch (attachment)
1094 {
Geoff Langfa125c92017-10-24 13:01:46 -04001095 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001096 case GL_DEPTH_ATTACHMENT:
1097 case GL_STENCIL_ATTACHMENT:
1098 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001099
He Yunchaoced53ae2016-11-29 15:00:51 +08001100 case GL_DEPTH_STENCIL_ATTACHMENT:
1101 if (!context->getExtensions().webglCompatibility &&
1102 context->getClientMajorVersion() < 3)
1103 {
Geoff Langfa125c92017-10-24 13:01:46 -04001104 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001105 return false;
1106 }
1107 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001108
He Yunchaoced53ae2016-11-29 15:00:51 +08001109 default:
Geoff Langfa125c92017-10-24 13:01:46 -04001110 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001111 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001112 }
1113 }
1114
1115 return true;
1116}
1117
Jamie Madill5b772312018-03-08 20:28:32 -05001118bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001119 GLenum target,
1120 GLsizei samples,
1121 GLenum internalformat,
1122 GLsizei width,
1123 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124{
1125 switch (target)
1126 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001127 case GL_RENDERBUFFER:
1128 break;
1129 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001130 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001132 }
1133
1134 if (width < 0 || height < 0 || samples < 0)
1135 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001136 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001137 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001138 }
1139
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001140 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1141 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1142
1143 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001144 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001146 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001147 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001148 }
1149
1150 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1151 // 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 -08001152 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001153 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001154 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001156 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001157 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001158 }
1159
Geoff Langaae65a42014-05-26 12:43:44 -04001160 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001162 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001163 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001164 }
1165
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001166 GLuint handle = context->getGLState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 if (handle == 0)
1168 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001169 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001170 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001171 }
1172
1173 return true;
1174}
1175
Jamie Madill43da7c42018-08-01 11:34:49 -04001176bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001177 GLenum target,
1178 GLenum attachment,
1179 GLenum renderbuffertarget,
1180 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001181{
Geoff Lange8afa902017-09-27 15:00:43 -04001182 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001184 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001185 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001186 }
1187
Jamie Madill43da7c42018-08-01 11:34:49 -04001188 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001189
Jamie Madill84115c92015-04-23 15:00:07 -04001190 ASSERT(framebuffer);
1191 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001193 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001194 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001195 }
1196
Jamie Madillb4472272014-07-03 10:38:55 -04001197 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001198 {
Jamie Madillb4472272014-07-03 10:38:55 -04001199 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001200 }
1201
Jamie Madillab9d82c2014-01-21 16:38:14 -05001202 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1203 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1204 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1205 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1206 if (renderbuffer != 0)
1207 {
1208 if (!context->getRenderbuffer(renderbuffer))
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001212 }
1213 }
1214
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001215 return true;
1216}
1217
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001218bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001219 GLint srcX0,
1220 GLint srcY0,
1221 GLint srcX1,
1222 GLint srcY1,
1223 GLint dstX0,
1224 GLint dstY0,
1225 GLint dstX1,
1226 GLint dstY1,
1227 GLbitfield mask,
1228 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001229{
1230 switch (filter)
1231 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001232 case GL_NEAREST:
1233 break;
1234 case GL_LINEAR:
1235 break;
1236 default:
Olli Etuahof0e3c192018-08-15 13:37:21 +03001237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001238 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001239 }
1240
1241 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1242 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001243 ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001244 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001245 }
1246
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001247 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1248 // color buffer, leaving only nearest being unfiltered from above
1249 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1250 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001251 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001252 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001253 }
1254
Jamie Madill7f232932018-09-12 11:03:06 -04001255 const auto &glState = context->getGLState();
1256 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1257 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001258
1259 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001260 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001261 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001262 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001263 }
1264
Jamie Madill427064d2018-04-13 16:20:34 -04001265 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001266 {
Jamie Madill48faf802014-11-06 15:27:22 -05001267 return false;
1268 }
1269
Jamie Madill427064d2018-04-13 16:20:34 -04001270 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001271 {
Jamie Madill48faf802014-11-06 15:27:22 -05001272 return false;
1273 }
1274
Qin Jiajiaaef92162018-02-27 13:51:44 +08001275 if (readFramebuffer->id() == drawFramebuffer->id())
1276 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001277 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001278 return false;
1279 }
1280
Jamie Madille98b1b52018-03-08 09:47:23 -05001281 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001282 {
Geoff Langb1196682014-07-23 13:47:29 -04001283 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001284 }
1285
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001286 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1287 // always run it in order to avoid triggering driver bugs.
1288 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1289 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001290 {
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001291 ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitDimensionsOutOfRange);
1292 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001293 }
1294
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001295 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1296
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001297 if (mask & GL_COLOR_BUFFER_BIT)
1298 {
Jamie Madill7f232932018-09-12 11:03:06 -04001299 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1300 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001301
He Yunchao66a41a22016-12-15 16:45:05 +08001302 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001303 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001304 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001305
Geoff Langa15472a2015-08-11 11:48:03 -04001306 for (size_t drawbufferIdx = 0;
1307 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001308 {
Geoff Langa15472a2015-08-11 11:48:03 -04001309 const FramebufferAttachment *attachment =
1310 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1311 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001312 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001313 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001314
Geoff Langb2f3d052013-08-13 12:49:27 -04001315 // The GL ES 3.0.2 spec (pg 193) states that:
1316 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1318 // as well
1319 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1320 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001321 // Changes with EXT_color_buffer_float:
1322 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001323 GLenum readComponentType = readFormat.info->componentType;
1324 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001325 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001326 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001327 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001328 drawComponentType == GL_SIGNED_NORMALIZED);
1329
1330 if (extensions.colorBufferFloat)
1331 {
1332 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1333 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1334
1335 if (readFixedOrFloat != drawFixedOrFloat)
1336 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001337 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1338 BlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001339 return false;
1340 }
1341 }
1342 else if (readFixedPoint != drawFixedPoint)
1343 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001344 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1345 BlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001346 return false;
1347 }
1348
1349 if (readComponentType == GL_UNSIGNED_INT &&
1350 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001351 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001352 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1353 BlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001354 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001355 }
1356
Jamie Madill6163c752015-12-07 16:32:59 -05001357 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001358 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001359 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1360 BlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001361 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001362 }
1363
Jamie Madilla3944d42016-07-22 22:13:26 -04001364 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001365 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001366 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001367 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1368 BlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001369 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001370 }
Geoff Lange4915782017-04-12 15:19:07 -04001371
1372 if (context->getExtensions().webglCompatibility &&
1373 *readColorBuffer == *attachment)
1374 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001376 return false;
1377 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001378 }
1379 }
1380
Jamie Madilla3944d42016-07-22 22:13:26 -04001381 if ((readFormat.info->componentType == GL_INT ||
1382 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1383 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001384 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001386 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001387 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001388 }
He Yunchao66a41a22016-12-15 16:45:05 +08001389 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1390 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1391 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1392 // situation is an application error that would lead to a crash in ANGLE.
1393 else if (drawFramebuffer->hasEnabledDrawBuffer())
1394 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001396 return false;
1397 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001398 }
1399
He Yunchaoced53ae2016-11-29 15:00:51 +08001400 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001401 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1402 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001403 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001404 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001405 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001406 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001407 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001408 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001409 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001410
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001411 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001412 {
Kenneth Russell69382852017-07-21 16:38:44 -04001413 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001414 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001415 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1416 BlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001417 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001419
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001420 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001422 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1423 BlitMultisampledBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001424 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001425 }
Geoff Lange4915782017-04-12 15:19:07 -04001426
1427 if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer)
1428 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001429 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001430 return false;
1431 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001432 }
He Yunchao66a41a22016-12-15 16:45:05 +08001433 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1434 else if (drawBuffer)
1435 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001437 return false;
1438 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001439 }
1440 }
1441
Martin Radeva3ed4572017-07-27 18:29:37 +03001442 // ANGLE_multiview, Revision 1:
1443 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001444 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1445 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1446 // views in the current read framebuffer is more than one.
1447 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001448 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001449 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001450 return false;
1451 }
1452 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1453 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001454 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001455 return false;
1456 }
1457
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001458 return true;
1459}
1460
Jamie Madill4928b7c2017-06-20 12:57:39 -04001461bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001462 GLint x,
1463 GLint y,
1464 GLsizei width,
1465 GLsizei height,
1466 GLenum format,
1467 GLenum type,
1468 GLsizei bufSize,
1469 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001470 GLsizei *columns,
1471 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001472 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001473{
1474 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001475 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001476 return false;
1477 }
1478
Brandon Jonesd1049182018-03-28 10:02:20 -07001479 GLsizei writeLength = 0;
1480 GLsizei writeColumns = 0;
1481 GLsizei writeRows = 0;
1482
1483 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1484 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001485 {
Geoff Langb1196682014-07-23 13:47:29 -04001486 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001487 }
1488
Brandon Jonesd1049182018-03-28 10:02:20 -07001489 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001490 {
Geoff Langb1196682014-07-23 13:47:29 -04001491 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001492 }
1493
Brandon Jonesd1049182018-03-28 10:02:20 -07001494 SetRobustLengthParam(length, writeLength);
1495 SetRobustLengthParam(columns, writeColumns);
1496 SetRobustLengthParam(rows, writeRows);
1497
Jamie Madillc29968b2016-01-20 11:17:23 -05001498 return true;
1499}
1500
1501bool ValidateReadnPixelsEXT(Context *context,
1502 GLint x,
1503 GLint y,
1504 GLsizei width,
1505 GLsizei height,
1506 GLenum format,
1507 GLenum type,
1508 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001509 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001510{
1511 if (bufSize < 0)
1512 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001513 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001514 return false;
1515 }
1516
Geoff Lang62fce5b2016-09-30 10:46:35 -04001517 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001518 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001519}
Jamie Madill26e91952014-03-05 15:01:27 -05001520
Jamie Madill4928b7c2017-06-20 12:57:39 -04001521bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001522 GLint x,
1523 GLint y,
1524 GLsizei width,
1525 GLsizei height,
1526 GLenum format,
1527 GLenum type,
1528 GLsizei bufSize,
1529 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001530 GLsizei *columns,
1531 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001532 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001533{
Brandon Jonesd1049182018-03-28 10:02:20 -07001534 GLsizei writeLength = 0;
1535 GLsizei writeColumns = 0;
1536 GLsizei writeRows = 0;
1537
Geoff Lang62fce5b2016-09-30 10:46:35 -04001538 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001539 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001540 return false;
1541 }
1542
Brandon Jonesd1049182018-03-28 10:02:20 -07001543 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1544 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001545 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001546 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001547 }
1548
Brandon Jonesd1049182018-03-28 10:02:20 -07001549 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001550 {
1551 return false;
1552 }
1553
Brandon Jonesd1049182018-03-28 10:02:20 -07001554 SetRobustLengthParam(length, writeLength);
1555 SetRobustLengthParam(columns, writeColumns);
1556 SetRobustLengthParam(rows, writeRows);
1557
Geoff Lang62fce5b2016-09-30 10:46:35 -04001558 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001559}
1560
Jamie Madill43da7c42018-08-01 11:34:49 -04001561bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001562{
1563 if (!context->getExtensions().occlusionQueryBoolean &&
1564 !context->getExtensions().disjointTimerQuery)
1565 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001566 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001567 return false;
1568 }
1569
Olli Etuaho41997e72016-03-10 13:38:39 +02001570 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001571}
1572
Jamie Madill43da7c42018-08-01 11:34:49 -04001573bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001574{
1575 if (!context->getExtensions().occlusionQueryBoolean &&
1576 !context->getExtensions().disjointTimerQuery)
1577 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001578 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001579 return false;
1580 }
1581
Olli Etuaho41997e72016-03-10 13:38:39 +02001582 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001583}
1584
Jamie Madill43da7c42018-08-01 11:34:49 -04001585bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001586{
1587 if (!context->getExtensions().occlusionQueryBoolean &&
1588 !context->getExtensions().disjointTimerQuery)
1589 {
1590 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
1591 return false;
1592 }
1593
1594 return true;
1595}
1596
Jamie Madill43da7c42018-08-01 11:34:49 -04001597bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001598{
1599 if (!ValidQueryType(context, target))
1600 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001602 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001603 }
1604
1605 if (id == 0)
1606 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001607 context->handleError(InvalidOperation() << "Query id is 0");
Geoff Langb1196682014-07-23 13:47:29 -04001608 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001609 }
1610
1611 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1612 // of zero, if the active query object name for <target> is non-zero (for the
1613 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1614 // the active query for either target is non-zero), if <id> is the name of an
1615 // existing query object whose type does not match <target>, or if <id> is the
1616 // active query object name for any query type, the error INVALID_OPERATION is
1617 // generated.
1618
1619 // Ensure no other queries are active
1620 // NOTE: If other queries than occlusion are supported, we will need to check
1621 // separately that:
1622 // a) The query ID passed is not the current active query for any target/type
1623 // b) There are no active queries for the requested target (and in the case
1624 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1625 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001626
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001627 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001628 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001629 context->handleError(InvalidOperation() << "Other query is active");
Geoff Langb1196682014-07-23 13:47:29 -04001630 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001631 }
1632
1633 Query *queryObject = context->getQuery(id, true, target);
1634
1635 // check that name was obtained with glGenQueries
1636 if (!queryObject)
1637 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001638 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001639 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001640 }
1641
1642 // check for type mismatch
1643 if (queryObject->getType() != target)
1644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001645 context->handleError(InvalidOperation() << "Query type does not match target");
Geoff Langb1196682014-07-23 13:47:29 -04001646 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001647 }
1648
1649 return true;
1650}
1651
Jamie Madill43da7c42018-08-01 11:34:49 -04001652bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001653{
1654 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001655 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001656 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001657 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001658 return false;
1659 }
1660
1661 return ValidateBeginQueryBase(context, target, id);
1662}
1663
Jamie Madill43da7c42018-08-01 11:34:49 -04001664bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001665{
1666 if (!ValidQueryType(context, target))
1667 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001668 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001669 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001670 }
1671
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001672 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001673
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001674 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001675 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001676 context->handleError(InvalidOperation() << "Query target not active");
Geoff Langb1196682014-07-23 13:47:29 -04001677 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001678 }
1679
Jamie Madill45c785d2014-05-13 14:09:34 -04001680 return true;
1681}
1682
Jamie Madill43da7c42018-08-01 11:34:49 -04001683bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001684{
1685 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001686 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001687 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001688 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001689 return false;
1690 }
1691
1692 return ValidateEndQueryBase(context, target);
1693}
1694
Corentin Wallezad3ae902018-03-09 13:40:42 -05001695bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001696{
1697 if (!context->getExtensions().disjointTimerQuery)
1698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001699 context->handleError(InvalidOperation() << "Disjoint timer query not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001700 return false;
1701 }
1702
Corentin Wallezad3ae902018-03-09 13:40:42 -05001703 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001704 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001705 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001706 return false;
1707 }
1708
1709 Query *queryObject = context->getQuery(id, true, target);
1710 if (queryObject == nullptr)
1711 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001712 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001713 return false;
1714 }
1715
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001716 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001717 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001718 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001719 return false;
1720 }
1721
1722 return true;
1723}
1724
Corentin Wallezad3ae902018-03-09 13:40:42 -05001725bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001726{
Geoff Lang2186c382016-10-14 10:54:54 -04001727 if (numParams)
1728 {
1729 *numParams = 0;
1730 }
1731
Corentin Wallezad3ae902018-03-09 13:40:42 -05001732 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001733 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001734 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001735 return false;
1736 }
1737
1738 switch (pname)
1739 {
1740 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001741 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum() << "Cannot use current query for timestamp");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001744 return false;
1745 }
1746 break;
1747 case GL_QUERY_COUNTER_BITS_EXT:
1748 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001749 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001750 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001751 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001752 return false;
1753 }
1754 break;
1755 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001756 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001757 return false;
1758 }
1759
Geoff Lang2186c382016-10-14 10:54:54 -04001760 if (numParams)
1761 {
1762 // All queries return only one value
1763 *numParams = 1;
1764 }
1765
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001766 return true;
1767}
1768
Corentin Wallezad3ae902018-03-09 13:40:42 -05001769bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001770{
1771 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001772 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001773 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001774 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001775 return false;
1776 }
1777
Geoff Lang2186c382016-10-14 10:54:54 -04001778 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001779}
1780
Geoff Lang2186c382016-10-14 10:54:54 -04001781bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001782 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001783 GLenum pname,
1784 GLsizei bufSize,
1785 GLsizei *length,
1786 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001787{
Geoff Lang2186c382016-10-14 10:54:54 -04001788 if (!ValidateRobustEntryPoint(context, bufSize))
1789 {
1790 return false;
1791 }
1792
Brandon Jonesd1049182018-03-28 10:02:20 -07001793 GLsizei numParams = 0;
1794
1795 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001796 {
1797 return false;
1798 }
1799
Brandon Jonesd1049182018-03-28 10:02:20 -07001800 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001801 {
1802 return false;
1803 }
1804
Brandon Jonesd1049182018-03-28 10:02:20 -07001805 SetRobustLengthParam(length, numParams);
1806
Geoff Lang2186c382016-10-14 10:54:54 -04001807 return true;
1808}
1809
1810bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1811{
1812 if (numParams)
1813 {
1814 *numParams = 0;
1815 }
1816
Corentin Wallezad3ae902018-03-09 13:40:42 -05001817 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001818
1819 if (!queryObject)
1820 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001821 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001822 return false;
1823 }
1824
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001825 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001826 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001827 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001828 return false;
1829 }
1830
1831 switch (pname)
1832 {
1833 case GL_QUERY_RESULT_EXT:
1834 case GL_QUERY_RESULT_AVAILABLE_EXT:
1835 break;
1836
1837 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001838 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001839 return false;
1840 }
1841
Geoff Lang2186c382016-10-14 10:54:54 -04001842 if (numParams)
1843 {
1844 *numParams = 1;
1845 }
1846
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001847 return true;
1848}
1849
1850bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1851{
1852 if (!context->getExtensions().disjointTimerQuery)
1853 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001854 context->handleError(InvalidOperation() << "Timer query extension not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001855 return false;
1856 }
Geoff Lang2186c382016-10-14 10:54:54 -04001857 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1858}
1859
1860bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1861 GLuint id,
1862 GLenum pname,
1863 GLsizei bufSize,
1864 GLsizei *length,
1865 GLint *params)
1866{
1867 if (!context->getExtensions().disjointTimerQuery)
1868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001869 context->handleError(InvalidOperation() << "Timer query extension not enabled");
Geoff Lang2186c382016-10-14 10:54:54 -04001870 return false;
1871 }
1872
1873 if (!ValidateRobustEntryPoint(context, bufSize))
1874 {
1875 return false;
1876 }
1877
Brandon Jonesd1049182018-03-28 10:02:20 -07001878 GLsizei numParams = 0;
1879
1880 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001881 {
1882 return false;
1883 }
1884
Brandon Jonesd1049182018-03-28 10:02:20 -07001885 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001886 {
1887 return false;
1888 }
1889
Brandon Jonesd1049182018-03-28 10:02:20 -07001890 SetRobustLengthParam(length, numParams);
1891
Geoff Lang2186c382016-10-14 10:54:54 -04001892 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001893}
1894
1895bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1896{
1897 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001898 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001900 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001901 return false;
1902 }
Geoff Lang2186c382016-10-14 10:54:54 -04001903 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1904}
1905
1906bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1907 GLuint id,
1908 GLenum pname,
1909 GLsizei bufSize,
1910 GLsizei *length,
1911 GLuint *params)
1912{
1913 if (!context->getExtensions().disjointTimerQuery &&
1914 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1915 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001916 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001917 return false;
1918 }
1919
1920 if (!ValidateRobustEntryPoint(context, bufSize))
1921 {
1922 return false;
1923 }
1924
Brandon Jonesd1049182018-03-28 10:02:20 -07001925 GLsizei numParams = 0;
1926
1927 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001928 {
1929 return false;
1930 }
1931
Brandon Jonesd1049182018-03-28 10:02:20 -07001932 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001933 {
1934 return false;
1935 }
1936
Brandon Jonesd1049182018-03-28 10:02:20 -07001937 SetRobustLengthParam(length, numParams);
1938
Geoff Lang2186c382016-10-14 10:54:54 -04001939 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001940}
1941
1942bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1943{
1944 if (!context->getExtensions().disjointTimerQuery)
1945 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001946 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001947 return false;
1948 }
Geoff Lang2186c382016-10-14 10:54:54 -04001949 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1950}
1951
1952bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1953 GLuint id,
1954 GLenum pname,
1955 GLsizei bufSize,
1956 GLsizei *length,
1957 GLint64 *params)
1958{
1959 if (!context->getExtensions().disjointTimerQuery)
1960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001962 return false;
1963 }
1964
1965 if (!ValidateRobustEntryPoint(context, bufSize))
1966 {
1967 return false;
1968 }
1969
Brandon Jonesd1049182018-03-28 10:02:20 -07001970 GLsizei numParams = 0;
1971
1972 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001973 {
1974 return false;
1975 }
1976
Brandon Jonesd1049182018-03-28 10:02:20 -07001977 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001978 {
1979 return false;
1980 }
1981
Brandon Jonesd1049182018-03-28 10:02:20 -07001982 SetRobustLengthParam(length, numParams);
1983
Geoff Lang2186c382016-10-14 10:54:54 -04001984 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001985}
1986
1987bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
1988{
1989 if (!context->getExtensions().disjointTimerQuery)
1990 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001991 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001992 return false;
1993 }
Geoff Lang2186c382016-10-14 10:54:54 -04001994 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1995}
1996
1997bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
1998 GLuint id,
1999 GLenum pname,
2000 GLsizei bufSize,
2001 GLsizei *length,
2002 GLuint64 *params)
2003{
2004 if (!context->getExtensions().disjointTimerQuery)
2005 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002006 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002007 return false;
2008 }
2009
2010 if (!ValidateRobustEntryPoint(context, bufSize))
2011 {
2012 return false;
2013 }
2014
Brandon Jonesd1049182018-03-28 10:02:20 -07002015 GLsizei numParams = 0;
2016
2017 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002018 {
2019 return false;
2020 }
2021
Brandon Jonesd1049182018-03-28 10:02:20 -07002022 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002023 {
2024 return false;
2025 }
2026
Brandon Jonesd1049182018-03-28 10:02:20 -07002027 SetRobustLengthParam(length, numParams);
2028
Geoff Lang2186c382016-10-14 10:54:54 -04002029 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002030}
2031
Jamie Madill5b772312018-03-08 20:28:32 -05002032bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002033 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002034 GLint location,
2035 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002036 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002037{
Jiajia Qin5451d532017-11-16 17:16:34 +08002038 // TODO(Jiajia): Add image uniform check in future.
2039 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002040 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002041 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002042 return false;
2043 }
2044
Jiajia Qin5451d532017-11-16 17:16:34 +08002045 if (!program)
2046 {
2047 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidProgramName);
2048 return false;
2049 }
2050
2051 if (!program->isLinked())
2052 {
2053 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
2054 return false;
2055 }
2056
2057 if (location == -1)
2058 {
2059 // Silently ignore the uniform command
2060 return false;
2061 }
2062
2063 const auto &uniformLocations = program->getUniformLocations();
2064 size_t castedLocation = static_cast<size_t>(location);
2065 if (castedLocation >= uniformLocations.size())
2066 {
2067 context->handleError(InvalidOperation() << "Invalid uniform location");
2068 return false;
2069 }
2070
2071 const auto &uniformLocation = uniformLocations[castedLocation];
2072 if (uniformLocation.ignored)
2073 {
2074 // Silently ignore the uniform command
2075 return false;
2076 }
2077
2078 if (!uniformLocation.used())
2079 {
2080 context->handleError(InvalidOperation());
2081 return false;
2082 }
2083
2084 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2085
2086 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002087 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002088 {
2089 context->handleError(InvalidOperation());
2090 return false;
2091 }
2092
2093 *uniformOut = &uniform;
2094 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002095}
2096
Jamie Madill5b772312018-03-08 20:28:32 -05002097bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002098 GLenum uniformType,
2099 GLsizei count,
2100 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002101{
Jiajia Qin5451d532017-11-16 17:16:34 +08002102 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2103 // It is compatible with INT or BOOL.
2104 // Do these cheap tests first, for a little extra speed.
2105 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002106 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002107 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002108 }
2109
Jiajia Qin5451d532017-11-16 17:16:34 +08002110 if (IsSamplerType(uniformType))
2111 {
2112 // Check that the values are in range.
2113 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2114 for (GLsizei i = 0; i < count; ++i)
2115 {
2116 if (value[i] < 0 || value[i] >= max)
2117 {
2118 context->handleError(InvalidValue() << "sampler uniform value out of range");
2119 return false;
2120 }
2121 }
2122 return true;
2123 }
2124
2125 context->handleError(InvalidOperation() << "wrong type of value for uniform");
2126 return false;
2127}
2128
Jamie Madill5b772312018-03-08 20:28:32 -05002129bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002130{
2131 // Check that the value type is compatible with uniform type.
2132 if (valueType == uniformType)
2133 {
2134 return true;
2135 }
2136
2137 context->handleError(InvalidOperation() << "wrong type of value for uniform");
2138 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002139}
2140
Jamie Madill5b772312018-03-08 20:28:32 -05002141bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002142{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002143 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002144 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002145 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2146 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002147}
2148
Jamie Madill5b772312018-03-08 20:28:32 -05002149bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002150{
2151 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002152 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002153 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2154 ValidateUniform1ivValue(context, uniform->type, count, value);
2155}
2156
Jamie Madill5b772312018-03-08 20:28:32 -05002157bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002158 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002159 GLint location,
2160 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002161 GLboolean transpose)
2162{
Geoff Lang92019432017-11-20 13:09:34 -05002163 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002164 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002165 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002166 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002167 }
2168
Jamie Madill62d31cb2015-09-11 13:25:51 -04002169 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002170 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002171 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2172 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002173}
2174
Jamie Madill5b772312018-03-08 20:28:32 -05002175bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002176{
2177 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002179 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04002180 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002181 }
2182
Jamie Madill0af26e12015-03-05 19:54:33 -05002183 const Caps &caps = context->getCaps();
2184
Jamie Madill893ab082014-05-16 16:56:10 -04002185 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2186 {
2187 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2188
Jamie Madill0af26e12015-03-05 19:54:33 -05002189 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002191 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002192 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002193 }
2194 }
2195
2196 switch (pname)
2197 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002198 case GL_TEXTURE_BINDING_2D:
2199 case GL_TEXTURE_BINDING_CUBE_MAP:
2200 case GL_TEXTURE_BINDING_3D:
2201 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002202 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002203 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002204 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002205 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002206 {
2207 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
2208 return false;
2209 }
2210 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002211 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2212 if (!context->getExtensions().textureRectangle)
2213 {
2214 context->handleError(InvalidEnum()
2215 << "ANGLE_texture_rectangle extension not present");
2216 return false;
2217 }
2218 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002219 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2220 if (!context->getExtensions().eglStreamConsumerExternal &&
2221 !context->getExtensions().eglImageExternal)
2222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002223 context->handleError(InvalidEnum() << "Neither NV_EGL_stream_consumer_external "
2224 "nor GL_OES_EGL_image_external "
2225 "extensions enabled");
He Yunchaoced53ae2016-11-29 15:00:51 +08002226 return false;
2227 }
2228 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002229
He Yunchaoced53ae2016-11-29 15:00:51 +08002230 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2231 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002232 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002233 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2234 ASSERT(readFramebuffer);
2235
Jamie Madill427064d2018-04-13 16:20:34 -04002236 if (!ValidateFramebufferComplete<InvalidOperation>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002237 {
Geoff Langb1196682014-07-23 13:47:29 -04002238 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002239 }
2240
Jamie Madille98b1b52018-03-08 09:47:23 -05002241 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002242 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002243 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002244 return false;
2245 }
2246
Jamie Madille98b1b52018-03-08 09:47:23 -05002247 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002248 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002250 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002251 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002252 }
2253 }
2254 break;
2255
He Yunchaoced53ae2016-11-29 15:00:51 +08002256 default:
2257 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002258 }
2259
2260 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002261 if (*numParams == 0)
2262 {
2263 return false;
2264 }
2265
2266 return true;
2267}
2268
Brandon Jonesd1049182018-03-28 10:02:20 -07002269bool ValidateGetBooleanvRobustANGLE(Context *context,
2270 GLenum pname,
2271 GLsizei bufSize,
2272 GLsizei *length,
2273 GLboolean *params)
2274{
2275 GLenum nativeType;
2276 unsigned int numParams = 0;
2277
2278 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2279 {
2280 return false;
2281 }
2282
2283 SetRobustLengthParam(length, numParams);
2284
2285 return true;
2286}
2287
2288bool ValidateGetFloatvRobustANGLE(Context *context,
2289 GLenum pname,
2290 GLsizei bufSize,
2291 GLsizei *length,
2292 GLfloat *params)
2293{
2294 GLenum nativeType;
2295 unsigned int numParams = 0;
2296
2297 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2298 {
2299 return false;
2300 }
2301
2302 SetRobustLengthParam(length, numParams);
2303
2304 return true;
2305}
2306
2307bool ValidateGetIntegervRobustANGLE(Context *context,
2308 GLenum pname,
2309 GLsizei bufSize,
2310 GLsizei *length,
2311 GLint *data)
2312{
2313 GLenum nativeType;
2314 unsigned int numParams = 0;
2315
2316 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2317 {
2318 return false;
2319 }
2320
2321 SetRobustLengthParam(length, numParams);
2322
2323 return true;
2324}
2325
2326bool ValidateGetInteger64vRobustANGLE(Context *context,
2327 GLenum pname,
2328 GLsizei bufSize,
2329 GLsizei *length,
2330 GLint64 *data)
2331{
2332 GLenum nativeType;
2333 unsigned int numParams = 0;
2334
2335 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2336 {
2337 return false;
2338 }
2339
2340 if (nativeType == GL_INT_64_ANGLEX)
2341 {
2342 CastStateValues(context, nativeType, pname, numParams, data);
2343 return false;
2344 }
2345
2346 SetRobustLengthParam(length, numParams);
2347 return true;
2348}
2349
Jamie Madill5b772312018-03-08 20:28:32 -05002350bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002351 GLenum pname,
2352 GLsizei bufSize,
2353 GLenum *nativeType,
2354 unsigned int *numParams)
2355{
2356 if (!ValidateRobustEntryPoint(context, bufSize))
2357 {
2358 return false;
2359 }
2360
2361 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2362 {
2363 return false;
2364 }
2365
2366 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002367 {
2368 return false;
2369 }
2370
2371 return true;
2372}
2373
Jamie Madill5b772312018-03-08 20:28:32 -05002374bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002375 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002376 GLint level,
2377 GLenum internalformat,
2378 bool isSubImage,
2379 GLint xoffset,
2380 GLint yoffset,
2381 GLint zoffset,
2382 GLint x,
2383 GLint y,
2384 GLsizei width,
2385 GLsizei height,
2386 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002387 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002388{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002389 TextureType texType = TextureTargetToType(target);
2390
Brandon Jones6cad5662017-06-14 13:25:13 -07002391 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002392 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002393 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
2394 return false;
2395 }
2396
2397 if (width < 0 || height < 0)
2398 {
2399 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002400 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002401 }
2402
He Yunchaoced53ae2016-11-29 15:00:51 +08002403 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2404 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002405 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002406 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002407 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002408 }
2409
2410 if (border != 0)
2411 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002412 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002413 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002414 }
2415
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002416 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002417 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002418 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002419 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002420 }
2421
Jamie Madill43da7c42018-08-01 11:34:49 -04002422 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002423 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002424 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002425 {
Geoff Langb1196682014-07-23 13:47:29 -04002426 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002427 }
2428
Jamie Madille98b1b52018-03-08 09:47:23 -05002429 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002430 {
Geoff Langb1196682014-07-23 13:47:29 -04002431 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002432 }
2433
Martin Radev138064f2016-07-15 12:03:41 +03002434 if (readFramebuffer->getReadBufferState() == GL_NONE)
2435 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002437 return false;
2438 }
2439
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002440 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2441 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002442 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002443 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002444 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2445 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002447 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002448 return false;
2449 }
2450
Martin Radev04e2c3b2017-07-27 16:54:35 +03002451 // ANGLE_multiview spec, Revision 1:
2452 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2453 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002454 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2455 // framebuffer is more than one.
2456 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002457 {
2458 context->handleError(InvalidFramebufferOperation()
2459 << "The active read framebuffer object has multiview attachments.");
2460 return false;
2461 }
2462
Jamie Madill43da7c42018-08-01 11:34:49 -04002463 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002464
Geoff Langaae65a42014-05-26 12:43:44 -04002465 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002466 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002467 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002468 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002469 maxDimension = caps.max2DTextureSize;
2470 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002471
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002472 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002473 maxDimension = caps.maxCubeMapTextureSize;
2474 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002475
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002476 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002477 maxDimension = caps.maxRectangleTextureSize;
2478 break;
2479
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002480 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002481 maxDimension = caps.max2DTextureSize;
2482 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002483
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002484 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002485 maxDimension = caps.max3DTextureSize;
2486 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002487
He Yunchaoced53ae2016-11-29 15:00:51 +08002488 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002489 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08002490 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002491 }
2492
Jamie Madill43da7c42018-08-01 11:34:49 -04002493 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002494 if (!texture)
2495 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002497 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002498 }
2499
Geoff Lang69cce582015-09-17 13:20:36 -04002500 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002501 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002502 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002503 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002504 }
2505
Jamie Madill43da7c42018-08-01 11:34:49 -04002506 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002507 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002508 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002509
Geoff Lang966c9402017-04-18 12:38:27 -04002510 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002511 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002512 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05002513 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002514 }
2515
2516 if (isSubImage)
2517 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002518 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2519 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2520 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002521 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002522 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002523 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002524 }
2525 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002526 else
2527 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002528 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002530 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002531 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002532 }
2533
Geoff Langeb66a6e2016-10-31 13:06:12 -04002534 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002536 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002537 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002538 }
2539
2540 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002541 if (static_cast<int>(width) > maxLevelDimension ||
2542 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002544 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002545 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002546 }
2547 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002548
Jamie Madill0c8abca2016-07-22 20:21:26 -04002549 if (textureFormatOut)
2550 {
2551 *textureFormatOut = texture->getFormat(target, level);
2552 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002553
2554 // Detect texture copying feedback loops for WebGL.
2555 if (context->getExtensions().webglCompatibility)
2556 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002557 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002558 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002559 ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002560 return false;
2561 }
2562 }
2563
Jamie Madill560a8d82014-05-21 13:06:20 -04002564 return true;
2565}
2566
Jamie Madillb42162f2018-08-20 12:58:37 -04002567// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2568// completeness check.
2569const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002570{
2571 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002572 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002573
2574 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2575 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2576 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002577 VertexArray *vertexArray = state.getVertexArray();
2578 ASSERT(vertexArray);
2579
2580 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002581 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002582 return kErrorBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002583 }
2584
2585 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2586 // Section 6.10 of the WebGL 1.0 spec.
2587 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002588 ASSERT(framebuffer);
2589
Jamie Madille7d80f32018-08-08 15:49:23 -04002590 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2591 {
2592 ASSERT(framebuffer);
2593 const FramebufferAttachment *dsAttachment =
2594 framebuffer->getStencilOrDepthStencilAttachment();
2595 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2596 ASSERT(stencilBits <= 8);
2597
2598 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2599 if (depthStencilState.stencilTest && stencilBits > 0)
2600 {
2601 GLuint maxStencilValue = (1 << stencilBits) - 1;
2602
2603 bool differentRefs =
2604 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2605 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2606 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2607 (depthStencilState.stencilBackWritemask & maxStencilValue);
2608 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2609 (depthStencilState.stencilBackMask & maxStencilValue);
2610
2611 if (differentRefs || differentWritemasks || differentMasks)
2612 {
2613 if (!extensions.webglCompatibility)
2614 {
2615 WARN() << "This ANGLE implementation does not support separate front/back "
2616 "stencil writemasks, reference values, or stencil mask values.";
2617 }
Jamie Madillb42162f2018-08-20 12:58:37 -04002618 return kErrorStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002619 }
2620 }
2621 }
2622
2623 if (!framebuffer->isComplete(context))
2624 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002625 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
2626 return kErrorDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002627 }
2628
2629 if (context->getStateCache().hasAnyEnabledClientAttrib())
2630 {
2631 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2632 {
2633 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2634 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2635 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2636 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madillb42162f2018-08-20 12:58:37 -04002637 return kErrorVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002638 }
2639
2640 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2641 {
2642 // This is an application error that would normally result in a crash, but we catch it
2643 // and return an error
Jamie Madillb42162f2018-08-20 12:58:37 -04002644 return kErrorVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002645 }
2646 }
2647
2648 // If we are running GLES1, there is no current program.
2649 if (context->getClientVersion() >= Version(2, 0))
2650 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002651 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002652 if (!program)
2653 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002654 return kErrorProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002655 }
2656
2657 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2658 // vertex shader stage or fragment shader stage is a undefined behaviour.
2659 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2660 // produce undefined result.
2661 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2662 !program->hasLinkedShaderStage(ShaderType::Fragment))
2663 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002664 return kErrorNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002665 }
2666
2667 if (!program->validateSamplers(nullptr, context->getCaps()))
2668 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002669 return kErrorTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002670 }
2671
2672 if (extensions.multiview)
2673 {
2674 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2675 const int framebufferNumViews = framebuffer->getNumViews();
2676 if (framebufferNumViews != programNumViews)
2677 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002678 return kErrorMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002679 }
2680
2681 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2682 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2683 framebufferNumViews > 1)
2684 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002685 return kErrorMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002686 }
2687
2688 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2689 state.isQueryActive(QueryType::TimeElapsed))
2690 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002691 return kErrorMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002692 }
2693 }
2694
2695 // Uniform buffer validation
2696 for (unsigned int uniformBlockIndex = 0;
2697 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2698 {
2699 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002700 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002701 const OffsetBindingPointer<Buffer> &uniformBuffer =
2702 state.getIndexedUniformBuffer(blockBinding);
2703
2704 if (uniformBuffer.get() == nullptr)
2705 {
2706 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002707 return kErrorUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002708 }
2709
2710 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2711 if (uniformBufferSize < uniformBlock.dataSize)
2712 {
2713 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002714 return kErrorUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002715 }
2716
2717 if (extensions.webglCompatibility &&
2718 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2719 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002720 return kErrorUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002721 }
2722 }
2723
2724 // Do some additonal WebGL-specific validation
2725 if (extensions.webglCompatibility)
2726 {
2727 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2728 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2729 transformFeedbackObject->buffersBoundForOtherUse())
2730 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002731 return kErrorTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002732 }
2733
2734 // Detect rendering feedback loops for WebGL.
2735 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2736 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002737 return kErrorFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002738 }
2739
2740 // Detect that the vertex shader input types match the attribute types
2741 if (!ValidateVertexShaderAttributeTypeMatch(context))
2742 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002743 return kErrorVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002744 }
2745
2746 // Detect that the color buffer types match the fragment shader output types
2747 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2748 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002749 return kErrorDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002750 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002751
2752 const VertexArray *vao = context->getGLState().getVertexArray();
2753 if (vao->hasTransformFeedbackBindingConflict(context))
2754 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002755 return kErrorVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002756 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002757 }
2758 }
2759
Jamie Madillb42162f2018-08-20 12:58:37 -04002760 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002761}
2762
Jamie Madill16e28fd2018-09-12 11:03:05 -04002763bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002764{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002765 const Extensions &extensions = context->getExtensions();
2766
Jamie Madill1aeb1312014-06-20 13:21:25 -04002767 switch (mode)
2768 {
Jamie Madill493f9572018-05-24 19:52:15 -04002769 case PrimitiveMode::Points:
2770 case PrimitiveMode::Lines:
2771 case PrimitiveMode::LineLoop:
2772 case PrimitiveMode::LineStrip:
2773 case PrimitiveMode::Triangles:
2774 case PrimitiveMode::TriangleStrip:
2775 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002776 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002777
Jamie Madill493f9572018-05-24 19:52:15 -04002778 case PrimitiveMode::LinesAdjacency:
2779 case PrimitiveMode::LineStripAdjacency:
2780 case PrimitiveMode::TrianglesAdjacency:
2781 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002782 if (!extensions.geometryShader)
2783 {
2784 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
2785 return false;
2786 }
2787 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002788 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002789 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002790 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002791 }
2792
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002793 // If we are running GLES1, there is no current program.
2794 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002795 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002796 const State &state = context->getGLState();
2797
Jamie Madill785e8a02018-10-04 17:42:00 -04002798 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002799 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002800
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002801 // Do geometry shader specific validations
2802 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002803 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002804 if (!IsCompatibleDrawModeWithGeometryShader(
2805 mode, program->getGeometryShaderInputPrimitiveType()))
2806 {
2807 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2808 IncompatibleDrawModeAgainstGeometryShader);
2809 return false;
2810 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002811 }
2812 }
2813
Jamie Madill9fdaa492018-02-16 10:52:11 -05002814 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002815}
2816
Jamie Madill16e28fd2018-09-12 11:03:05 -04002817bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
2818{
2819 if (!context->getStateCache().isValidDrawMode(mode))
2820 {
2821 return ValidateDrawMode(context, mode);
2822 }
2823
2824 if (count < 0)
2825 {
2826 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
2827 return false;
2828 }
2829
2830 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2831 if (drawStatesError)
2832 {
2833 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2834
2835 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2836 // Incomplete.
2837 GLenum errorCode =
2838 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2839 : GL_INVALID_OPERATION);
2840 context->handleError(Error(errorCode, errorMessage));
2841 return false;
2842 }
2843
2844 return true;
2845}
2846
Jamie Madill5b772312018-03-08 20:28:32 -05002847bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002848 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002849 GLint first,
2850 GLsizei count,
2851 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002852{
Jamie Madillfd716582014-06-06 17:09:04 -04002853 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002854 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002855 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002856 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002857 }
2858
Jamie Madill16e28fd2018-09-12 11:03:05 -04002859 if (count < 0)
2860 {
2861 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
2862 return false;
2863 }
2864
Jamie Madill7f232932018-09-12 11:03:06 -04002865 const State &state = context->getGLState();
2866 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002867 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002868 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002869 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002870 if (!ValidateTransformFeedbackPrimitiveMode(context,
2871 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002872 {
James Darpinian30b604d2018-03-12 17:26:57 -07002873 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
2874 return false;
2875 }
2876
2877 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2878 {
2879 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TransformFeedbackBufferTooSmall);
2880 return false;
2881 }
Jamie Madillfd716582014-06-06 17:09:04 -04002882 }
2883
Jamie Madill16e28fd2018-09-12 11:03:05 -04002884 if (!context->getStateCache().isValidDrawMode(mode))
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002885 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002886 return ValidateDrawMode(context, mode);
2887 }
2888
2889 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2890 if (drawStatesError)
2891 {
2892 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2893
2894 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2895 // Incomplete.
2896 GLenum errorCode =
2897 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2898 : GL_INVALID_OPERATION);
2899 context->handleError(Error(errorCode, errorMessage));
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002900 return false;
2901 }
2902
Corentin Wallez71168a02016-12-19 15:11:18 -08002903 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002904 // - first < 0 has been checked as an error condition.
2905 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002906 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002907 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002908 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002909 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002910 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2911 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2912 {
2913 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
2914 return false;
2915 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002916
Jamie Madill2da53562018-08-01 11:34:47 -04002917 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002918 {
2919 return false;
2920 }
Jamie Madillfd716582014-06-06 17:09:04 -04002921 }
2922
2923 return true;
2924}
2925
He Yunchaoced53ae2016-11-29 15:00:51 +08002926bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002927 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002928 GLint first,
2929 GLsizei count,
2930 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002931{
Geoff Lang63c5a592017-09-27 14:08:16 -04002932 if (!context->getExtensions().instancedArrays)
2933 {
2934 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
2935 return false;
2936 }
2937
Corentin Wallez170efbf2017-05-02 13:45:01 -04002938 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002939 {
2940 return false;
2941 }
2942
Corentin Wallez0dc97812017-06-22 14:38:44 -04002943 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002944}
2945
Jamie Madill493f9572018-05-24 19:52:15 -04002946bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, GLenum type)
Jamie Madillfd716582014-06-06 17:09:04 -04002947{
Jamie Madill250d33f2014-06-06 17:09:03 -04002948 switch (type)
2949 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002950 case GL_UNSIGNED_BYTE:
2951 case GL_UNSIGNED_SHORT:
2952 break;
2953 case GL_UNSIGNED_INT:
2954 if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
2955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002956 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002957 return false;
2958 }
2959 break;
2960 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002961 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002962 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002963 }
2964
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002965 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002966
Jamie Madill43da7c42018-08-01 11:34:49 -04002967 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002968 if (curTransformFeedback && curTransformFeedback->isActive() &&
2969 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002970 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002971 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2972 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2973 if (context->getExtensions().geometryShader)
2974 {
2975 if (!ValidateTransformFeedbackPrimitiveMode(
2976 context, curTransformFeedback->getPrimitiveMode(), mode))
2977 {
2978 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
2979 return false;
2980 }
2981 }
2982 else
2983 {
2984 // It is an invalid operation to call DrawElements, DrawRangeElements or
2985 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
2986 // 86)
2987 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2988 UnsupportedDrawModeForTransformFeedback);
2989 return false;
2990 }
Jamie Madill250d33f2014-06-06 17:09:03 -04002991 }
2992
Jiajia Qind9671222016-11-29 16:30:31 +08002993 return true;
2994}
2995
Jamie Madill5b772312018-03-08 20:28:32 -05002996bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002997 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04002998 GLsizei count,
2999 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003000 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003001 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08003002{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003003 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003004 return false;
3005
3006 const State &state = context->getGLState();
3007
Corentin Wallez170efbf2017-05-02 13:45:01 -04003008 if (!ValidateDrawBase(context, mode, count))
3009 {
3010 return false;
3011 }
3012
Jamie Madill43da7c42018-08-01 11:34:49 -04003013 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003014 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003015
Jamie Madill43da7c42018-08-01 11:34:49 -04003016 GLuint typeBytes = GetTypeInfo(type).bytes;
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003017
3018 if (context->getExtensions().webglCompatibility)
3019 {
3020 ASSERT(isPow2(typeBytes) && typeBytes > 0);
3021 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3022 {
3023 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3024 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3025 // data type passed to the call, or an INVALID_OPERATION error is generated.
Brandon Jones6cad5662017-06-14 13:25:13 -07003026 ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003027 return false;
3028 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003029
3030 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3031 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3032 // error is generated.
3033 if (reinterpret_cast<intptr_t>(indices) < 0)
3034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003035 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003036 return false;
3037 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003038 }
Jamie Madillcc73f242018-08-01 11:34:48 -04003039 else if (elementArrayBuffer && elementArrayBuffer->isMapped())
3040 {
3041 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3042 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the WebGL 2.0 API.
3043 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
3044 context->handleError(InvalidOperation() << "Index buffer is mapped.");
3045 return false;
3046 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003047
3048 if (context->getExtensions().webglCompatibility ||
3049 !context->getGLState().areClientArraysEnabled())
3050 {
Brandon Jones2a018152018-06-08 15:59:26 -07003051 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003052 {
3053 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003054 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3055 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Brandon Jones6cad5662017-06-14 13:25:13 -07003056 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003057 return false;
3058 }
3059 }
3060
Jamie Madill9fdaa492018-02-16 10:52:11 -05003061 if (count > 0 && !elementArrayBuffer && !indices)
Jamie Madillae3000b2014-08-25 15:47:51 -04003062 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003063 // This is an application error that would normally result in a crash, but we catch it and
3064 // return an error
3065 context->handleError(InvalidOperation() << "No element array buffer and no pointer.");
3066 return false;
3067 }
3068
3069 if (count > 0 && elementArrayBuffer)
3070 {
3071 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3072 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3073 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3074 constexpr uint64_t kMaxTypeSize = 8;
3075 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3076 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3077 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3078
3079 uint64_t typeSize = typeBytes;
3080 uint64_t elementCount = static_cast<uint64_t>(count);
3081 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3082
3083 // Doing the multiplication here is overflow-safe
3084 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3085
3086 // The offset can be any value, check for overflows
3087 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3088 if (elementDataSizeNoOffset > kUint64Max - offset)
Jamie Madillae3000b2014-08-25 15:47:51 -04003089 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003090 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
3091 return false;
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003092 }
Jamie Madill9fdaa492018-02-16 10:52:11 -05003093
3094 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3095 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003096 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003097 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
3098 return false;
3099 }
3100
3101 ASSERT(isPow2(typeSize) && typeSize > 0);
3102 if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0)
3103 {
3104 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedByteCountType);
Geoff Langb1196682014-07-23 13:47:29 -04003105 return false;
Jamie Madillae3000b2014-08-25 15:47:51 -04003106 }
James Darpiniane8a93c62018-01-04 18:02:24 -08003107
3108 if (context->getExtensions().webglCompatibility &&
3109 elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
3110 {
3111 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
3112 ElementArrayBufferBoundForTransformFeedback);
3113 return false;
3114 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003115 }
3116
Jamie Madill2da53562018-08-01 11:34:47 -04003117 if (!context->getExtensions().robustBufferAccessBehavior && count > 0 && primcount > 0)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003118 {
3119 // Use the parameter buffer to retrieve and cache the index range.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003120 const DrawCallParams &params = context->getParams<DrawCallParams>();
3121 ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
3122 const IndexRange &indexRange = params.getIndexRange();
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003123
3124 // If we use an index greater than our maximum supported index range, return an error.
3125 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
3126 // return an error if possible here.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003127 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003128 {
3129 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement);
3130 return false;
3131 }
3132
Jamie Madill2da53562018-08-01 11:34:47 -04003133 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003134 {
3135 return false;
3136 }
3137
3138 // No op if there are no real indices in the index data (all are primitive restart).
Jamie Madill6f5444d2018-03-14 10:08:11 -04003139 return (indexRange.vertexIndexCount > 0);
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003140 }
3141
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003142 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003143}
3144
Jamie Madill5b772312018-03-08 20:28:32 -05003145bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003146 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003147 GLsizei count,
3148 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003149 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003150 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003151{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003152 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003153}
3154
Geoff Lang3edfe032015-09-04 16:38:24 -04003155bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003156 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003157 GLsizei count,
3158 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003159 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003160 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003161{
Geoff Lang63c5a592017-09-27 14:08:16 -04003162 if (!context->getExtensions().instancedArrays)
3163 {
3164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3165 return false;
3166 }
3167
Corentin Wallez170efbf2017-05-02 13:45:01 -04003168 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003169 {
3170 return false;
3171 }
3172
Corentin Wallez0dc97812017-06-22 14:38:44 -04003173 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003174}
3175
He Yunchaoced53ae2016-11-29 15:00:51 +08003176bool ValidateFramebufferTextureBase(Context *context,
3177 GLenum target,
3178 GLenum attachment,
3179 GLuint texture,
3180 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003181{
Geoff Lange8afa902017-09-27 15:00:43 -04003182 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003183 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003184 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003185 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003186 }
3187
3188 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003189 {
3190 return false;
3191 }
3192
Jamie Madill55ec3b12014-07-03 10:38:57 -04003193 if (texture != 0)
3194 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003195 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003196
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003197 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003199 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04003200 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003201 }
3202
3203 if (level < 0)
3204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003205 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04003206 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003207 }
3208 }
3209
Jamie Madill43da7c42018-08-01 11:34:49 -04003210 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003211 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003212
Jamie Madill84115c92015-04-23 15:00:07 -04003213 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003214 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003215 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003216 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003217 }
3218
3219 return true;
3220}
3221
Geoff Langb1196682014-07-23 13:47:29 -04003222bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003223{
3224 if (program == 0)
3225 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003226 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04003227 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003228 }
3229
Jamie Madill43da7c42018-08-01 11:34:49 -04003230 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003231 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003232 {
3233 return false;
3234 }
3235
Jamie Madill0063c512014-08-25 15:47:53 -04003236 if (!programObject || !programObject->isLinked())
3237 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003238 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003239 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003240 }
3241
Geoff Lang7dd2e102014-11-10 15:19:26 -05003242 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003243 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003244 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04003245 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003246 }
3247
Jamie Madill0063c512014-08-25 15:47:53 -04003248 return true;
3249}
3250
Geoff Langf41d0ee2016-10-07 13:04:23 -04003251static bool ValidateSizedGetUniform(Context *context,
3252 GLuint program,
3253 GLint location,
3254 GLsizei bufSize,
3255 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003256{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003257 if (length)
3258 {
3259 *length = 0;
3260 }
3261
Jamie Madill78f41802014-08-25 15:47:55 -04003262 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003263 {
Jamie Madill78f41802014-08-25 15:47:55 -04003264 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003265 }
3266
Geoff Langf41d0ee2016-10-07 13:04:23 -04003267 if (bufSize < 0)
3268 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003269 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003270 return false;
3271 }
3272
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003273 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003274 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003275
Jamie Madill78f41802014-08-25 15:47:55 -04003276 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003277 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003278 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003279 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003280 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003281 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003282 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003283 }
3284
Geoff Langf41d0ee2016-10-07 13:04:23 -04003285 if (length)
3286 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003287 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003288 }
3289
Jamie Madill0063c512014-08-25 15:47:53 -04003290 return true;
3291}
3292
He Yunchaoced53ae2016-11-29 15:00:51 +08003293bool ValidateGetnUniformfvEXT(Context *context,
3294 GLuint program,
3295 GLint location,
3296 GLsizei bufSize,
3297 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003298{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003299 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003300}
3301
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003302bool ValidateGetnUniformfvRobustANGLE(Context *context,
3303 GLuint program,
3304 GLint location,
3305 GLsizei bufSize,
3306 GLsizei *length,
3307 GLfloat *params)
3308{
3309 UNIMPLEMENTED();
3310 return false;
3311}
3312
He Yunchaoced53ae2016-11-29 15:00:51 +08003313bool ValidateGetnUniformivEXT(Context *context,
3314 GLuint program,
3315 GLint location,
3316 GLsizei bufSize,
3317 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003318{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003319 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3320}
3321
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003322bool ValidateGetnUniformivRobustANGLE(Context *context,
3323 GLuint program,
3324 GLint location,
3325 GLsizei bufSize,
3326 GLsizei *length,
3327 GLint *params)
3328{
3329 UNIMPLEMENTED();
3330 return false;
3331}
3332
3333bool ValidateGetnUniformuivRobustANGLE(Context *context,
3334 GLuint program,
3335 GLint location,
3336 GLsizei bufSize,
3337 GLsizei *length,
3338 GLuint *params)
3339{
3340 UNIMPLEMENTED();
3341 return false;
3342}
3343
Geoff Langf41d0ee2016-10-07 13:04:23 -04003344bool ValidateGetUniformfvRobustANGLE(Context *context,
3345 GLuint program,
3346 GLint location,
3347 GLsizei bufSize,
3348 GLsizei *length,
3349 GLfloat *params)
3350{
3351 if (!ValidateRobustEntryPoint(context, bufSize))
3352 {
3353 return false;
3354 }
3355
Brandon Jonesd1049182018-03-28 10:02:20 -07003356 GLsizei writeLength = 0;
3357
Geoff Langf41d0ee2016-10-07 13:04:23 -04003358 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003359 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3360 {
3361 return false;
3362 }
3363
3364 SetRobustLengthParam(length, writeLength);
3365
3366 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003367}
3368
3369bool ValidateGetUniformivRobustANGLE(Context *context,
3370 GLuint program,
3371 GLint location,
3372 GLsizei bufSize,
3373 GLsizei *length,
3374 GLint *params)
3375{
3376 if (!ValidateRobustEntryPoint(context, bufSize))
3377 {
3378 return false;
3379 }
3380
Brandon Jonesd1049182018-03-28 10:02:20 -07003381 GLsizei writeLength = 0;
3382
Geoff Langf41d0ee2016-10-07 13:04:23 -04003383 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003384 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3385 {
3386 return false;
3387 }
3388
3389 SetRobustLengthParam(length, writeLength);
3390
3391 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003392}
3393
3394bool ValidateGetUniformuivRobustANGLE(Context *context,
3395 GLuint program,
3396 GLint location,
3397 GLsizei bufSize,
3398 GLsizei *length,
3399 GLuint *params)
3400{
3401 if (!ValidateRobustEntryPoint(context, bufSize))
3402 {
3403 return false;
3404 }
3405
3406 if (context->getClientMajorVersion() < 3)
3407 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08003408 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003409 return false;
3410 }
3411
Brandon Jonesd1049182018-03-28 10:02:20 -07003412 GLsizei writeLength = 0;
3413
Geoff Langf41d0ee2016-10-07 13:04:23 -04003414 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003415 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3416 {
3417 return false;
3418 }
3419
3420 SetRobustLengthParam(length, writeLength);
3421
3422 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003423}
3424
He Yunchaoced53ae2016-11-29 15:00:51 +08003425bool ValidateDiscardFramebufferBase(Context *context,
3426 GLenum target,
3427 GLsizei numAttachments,
3428 const GLenum *attachments,
3429 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003430{
3431 if (numAttachments < 0)
3432 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003433 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003434 return false;
3435 }
3436
3437 for (GLsizei i = 0; i < numAttachments; ++i)
3438 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003439 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003440 {
3441 if (defaultFramebuffer)
3442 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003443 ANGLE_VALIDATION_ERR(context, InvalidEnum(), DefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003444 return false;
3445 }
3446
3447 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003449 context->handleError(InvalidOperation() << "Requested color attachment is "
3450 "greater than the maximum supported "
3451 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003452 return false;
3453 }
3454 }
3455 else
3456 {
3457 switch (attachments[i])
3458 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003459 case GL_DEPTH_ATTACHMENT:
3460 case GL_STENCIL_ATTACHMENT:
3461 case GL_DEPTH_STENCIL_ATTACHMENT:
3462 if (defaultFramebuffer)
3463 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003464 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
3465 DefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003466 return false;
3467 }
3468 break;
3469 case GL_COLOR:
3470 case GL_DEPTH:
3471 case GL_STENCIL:
3472 if (!defaultFramebuffer)
3473 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003474 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
3475 DefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003476 return false;
3477 }
3478 break;
3479 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003480 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003481 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003482 }
3483 }
3484 }
3485
3486 return true;
3487}
3488
Austin Kinross6ee1e782015-05-29 17:05:37 -07003489bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3490{
Jamie Madill007530e2017-12-28 14:27:04 -05003491 if (!context->getExtensions().debugMarker)
3492 {
3493 // The debug marker calls should not set error state
3494 // However, it seems reasonable to set an error state if the extension is not enabled
3495 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3496 return false;
3497 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003498
Jamie Madill007530e2017-12-28 14:27:04 -05003499 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003500 if (length < 0)
3501 {
3502 return false;
3503 }
3504
3505 if (marker == nullptr)
3506 {
3507 return false;
3508 }
3509
3510 return true;
3511}
3512
3513bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3514{
Jamie Madill007530e2017-12-28 14:27:04 -05003515 if (!context->getExtensions().debugMarker)
3516 {
3517 // The debug marker calls should not set error state
3518 // However, it seems reasonable to set an error state if the extension is not enabled
3519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3520 return false;
3521 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003522
Jamie Madill007530e2017-12-28 14:27:04 -05003523 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003524 if (length < 0)
3525 {
3526 return false;
3527 }
3528
3529 if (length > 0 && marker == nullptr)
3530 {
3531 return false;
3532 }
3533
3534 return true;
3535}
3536
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003537bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003538{
Geoff Langa8406172015-07-21 16:53:39 -04003539 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003541 context->handleError(InvalidOperation());
Geoff Langa8406172015-07-21 16:53:39 -04003542 return false;
3543 }
3544
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003545 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003546 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003547 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003548 if (!context->getExtensions().eglImage)
3549 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003550 context->handleError(InvalidEnum()
3551 << "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003552 }
3553 break;
3554
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003555 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003556 if (!context->getExtensions().eglImageExternal)
3557 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003558 context->handleError(InvalidEnum() << "GL_TEXTURE_EXTERNAL_OES texture target "
3559 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003560 }
Geoff Langa8406172015-07-21 16:53:39 -04003561 break;
3562
3563 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003564 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003565 return false;
3566 }
3567
Rafael Cintron05a449a2018-06-20 18:08:04 -07003568 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003569
Jamie Madill61e16b42017-06-19 11:13:23 -04003570 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003571 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003572 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003573 context->handleError(InvalidValue() << "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003574 return false;
3575 }
3576
Jamie Madill007530e2017-12-28 14:27:04 -05003577 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003579 context->handleError(InvalidOperation()
3580 << "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003581 return false;
3582 }
3583
Yuly Novikov2eb54072018-08-22 16:41:26 -04003584 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003585 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003586 context->handleError(InvalidOperation()
3587 << "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003588 return false;
3589 }
3590
Geoff Langdcab33b2015-07-21 13:03:16 -04003591 return true;
3592}
3593
3594bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003595 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003596 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003597{
Geoff Langa8406172015-07-21 16:53:39 -04003598 if (!context->getExtensions().eglImage)
3599 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003600 context->handleError(InvalidOperation());
Geoff Langa8406172015-07-21 16:53:39 -04003601 return false;
3602 }
3603
3604 switch (target)
3605 {
3606 case GL_RENDERBUFFER:
3607 break;
3608
3609 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003611 return false;
3612 }
3613
Rafael Cintron05a449a2018-06-20 18:08:04 -07003614 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003615
Jamie Madill61e16b42017-06-19 11:13:23 -04003616 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003617 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003618 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003619 context->handleError(InvalidValue() << "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003620 return false;
3621 }
3622
Yuly Novikov2eb54072018-08-22 16:41:26 -04003623 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003624 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003625 context->handleError(InvalidOperation()
3626 << "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003627 return false;
3628 }
3629
Geoff Langdcab33b2015-07-21 13:03:16 -04003630 return true;
3631}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003632
3633bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3634{
Geoff Lang36167ab2015-12-07 10:27:14 -05003635 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003636 {
3637 // The default VAO should always exist
3638 ASSERT(array != 0);
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003639 context->handleError(InvalidOperation());
Austin Kinrossbc781f32015-10-26 09:27:38 -07003640 return false;
3641 }
3642
3643 return true;
3644}
3645
Geoff Langc5629752015-12-07 16:29:04 -05003646bool ValidateProgramBinaryBase(Context *context,
3647 GLuint program,
3648 GLenum binaryFormat,
3649 const void *binary,
3650 GLint length)
3651{
3652 Program *programObject = GetValidProgram(context, program);
3653 if (programObject == nullptr)
3654 {
3655 return false;
3656 }
3657
3658 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3659 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3660 programBinaryFormats.end())
3661 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003662 context->handleError(InvalidEnum() << "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003663 return false;
3664 }
3665
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003666 if (context->hasActiveTransformFeedback(program))
3667 {
3668 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003669 context->handleError(InvalidOperation() << "Cannot change program binary while program "
3670 "is associated with an active transform "
3671 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003672 return false;
3673 }
3674
Geoff Langc5629752015-12-07 16:29:04 -05003675 return true;
3676}
3677
3678bool ValidateGetProgramBinaryBase(Context *context,
3679 GLuint program,
3680 GLsizei bufSize,
3681 GLsizei *length,
3682 GLenum *binaryFormat,
3683 void *binary)
3684{
3685 Program *programObject = GetValidProgram(context, program);
3686 if (programObject == nullptr)
3687 {
3688 return false;
3689 }
3690
3691 if (!programObject->isLinked())
3692 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003693 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003694 return false;
3695 }
3696
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003697 if (context->getCaps().programBinaryFormats.empty())
3698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003699 context->handleError(InvalidOperation() << "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003700 return false;
3701 }
3702
Geoff Langc5629752015-12-07 16:29:04 -05003703 return true;
3704}
Jamie Madillc29968b2016-01-20 11:17:23 -05003705
Jamie Madill5b772312018-03-08 20:28:32 -05003706bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003707{
3708 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003709 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003710 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003711 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
3712 return false;
3713 }
3714 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3715 {
3716 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003717 return false;
3718 }
3719
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003720 ASSERT(context->getGLState().getDrawFramebuffer());
3721 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003722 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3723
3724 // This should come first before the check for the default frame buffer
3725 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3726 // rather than INVALID_OPERATION
3727 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3728 {
3729 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3730
3731 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003732 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3733 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003734 {
3735 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003736 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3737 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3738 // 3.1 is still a bit ambiguous about the error, but future specs are
3739 // expected to clarify that GL_INVALID_ENUM is the correct error.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003740 context->handleError(InvalidEnum() << "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003741 return false;
3742 }
3743 else if (bufs[colorAttachment] >= maxColorAttachment)
3744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003745 context->handleError(InvalidOperation()
3746 << "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003747 return false;
3748 }
3749 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3750 frameBufferId != 0)
3751 {
3752 // INVALID_OPERATION-GL is bound to buffer and ith argument
3753 // is not COLOR_ATTACHMENTi or NONE
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003754 context->handleError(InvalidOperation()
3755 << "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003756 return false;
3757 }
3758 }
3759
3760 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3761 // and n is not 1 or bufs is bound to value other than BACK and NONE
3762 if (frameBufferId == 0)
3763 {
3764 if (n != 1)
3765 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003766 context->handleError(InvalidOperation()
3767 << "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003768 return false;
3769 }
3770
3771 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003773 context->handleError(
3774 InvalidOperation()
3775 << "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003776 return false;
3777 }
3778 }
3779
3780 return true;
3781}
3782
Geoff Lang496c02d2016-10-20 11:38:11 -07003783bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003784 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003785 GLenum pname,
3786 GLsizei *length,
3787 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003788{
Geoff Lang496c02d2016-10-20 11:38:11 -07003789 if (length)
3790 {
3791 *length = 0;
3792 }
3793
3794 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3795 {
3796 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003797 InvalidOperation()
3798 << "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003799 return false;
3800 }
3801
Corentin Walleze4477002017-12-01 14:39:58 -05003802 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003803 {
Corentin Wallez336129f2017-10-17 15:55:40 -04003804 context->handleError(InvalidEnum() << "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003805 return false;
3806 }
3807
Geoff Lang496c02d2016-10-20 11:38:11 -07003808 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003809 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003810 case GL_BUFFER_MAP_POINTER:
3811 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003812
Geoff Lang496c02d2016-10-20 11:38:11 -07003813 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003814 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003815 return false;
3816 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003817
3818 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3819 // target bound to zero generate an INVALID_OPERATION error."
3820 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003821 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003822 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003823 context->handleError(InvalidOperation()
3824 << "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003825 return false;
3826 }
3827
Geoff Lang496c02d2016-10-20 11:38:11 -07003828 if (length)
3829 {
3830 *length = 1;
3831 }
3832
Olli Etuaho4f667482016-03-30 15:56:35 +03003833 return true;
3834}
3835
Corentin Wallez336129f2017-10-17 15:55:40 -04003836bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003837{
Corentin Walleze4477002017-12-01 14:39:58 -05003838 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003839 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003840 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003841 return false;
3842 }
3843
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003844 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003845
3846 if (buffer == nullptr || !buffer->isMapped())
3847 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003848 context->handleError(InvalidOperation() << "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003849 return false;
3850 }
3851
3852 return true;
3853}
3854
3855bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003856 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003857 GLintptr offset,
3858 GLsizeiptr length,
3859 GLbitfield access)
3860{
Corentin Walleze4477002017-12-01 14:39:58 -05003861 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003862 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003863 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003864 return false;
3865 }
3866
Brandon Jones6cad5662017-06-14 13:25:13 -07003867 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003868 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003869 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
3870 return false;
3871 }
3872
3873 if (length < 0)
3874 {
3875 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003876 return false;
3877 }
3878
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003879 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003880
3881 if (!buffer)
3882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003883 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003884 return false;
3885 }
3886
3887 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003888 CheckedNumeric<size_t> checkedOffset(offset);
3889 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003890
Jamie Madille2e406c2016-06-02 13:04:10 -04003891 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003892 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003893 context->handleError(InvalidValue() << "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003894 return false;
3895 }
3896
3897 // Check for invalid bits in the mask
3898 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3899 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3900 GL_MAP_UNSYNCHRONIZED_BIT;
3901
3902 if (access & ~(allAccessBits))
3903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003904 context->handleError(InvalidValue()
3905 << "Invalid access bits: 0x" << std::hex << std::uppercase << access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003906 return false;
3907 }
3908
3909 if (length == 0)
3910 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003911 context->handleError(InvalidOperation() << "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003912 return false;
3913 }
3914
3915 if (buffer->isMapped())
3916 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003917 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003918 return false;
3919 }
3920
3921 // Check for invalid bit combinations
3922 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3923 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003924 context->handleError(InvalidOperation()
3925 << "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003926 return false;
3927 }
3928
3929 GLbitfield writeOnlyBits =
3930 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3931
3932 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3933 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003934 context->handleError(InvalidOperation()
3935 << "Invalid access bits when mapping buffer for reading: 0x"
3936 << std::hex << std::uppercase << access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003937 return false;
3938 }
3939
3940 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3941 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003942 context->handleError(
3943 InvalidOperation()
3944 << "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003945 return false;
3946 }
Geoff Lang79f71042017-08-14 16:43:43 -04003947
3948 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003949}
3950
3951bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003952 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003953 GLintptr offset,
3954 GLsizeiptr length)
3955{
Brandon Jones6cad5662017-06-14 13:25:13 -07003956 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003958 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
3959 return false;
3960 }
3961
3962 if (length < 0)
3963 {
3964 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003965 return false;
3966 }
3967
Corentin Walleze4477002017-12-01 14:39:58 -05003968 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003969 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003970 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003971 return false;
3972 }
3973
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003974 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003975
3976 if (buffer == nullptr)
3977 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003978 context->handleError(InvalidOperation() << "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003979 return false;
3980 }
3981
3982 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
3983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003984 context->handleError(InvalidOperation()
3985 << "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003986 return false;
3987 }
3988
3989 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003990 CheckedNumeric<size_t> checkedOffset(offset);
3991 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003992
Jamie Madille2e406c2016-06-02 13:04:10 -04003993 if (!checkedSize.IsValid() ||
3994 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003995 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003996 context->handleError(InvalidValue()
3997 << "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003998 return false;
3999 }
4000
4001 return true;
4002}
4003
Olli Etuaho41997e72016-03-10 13:38:39 +02004004bool ValidateGenOrDelete(Context *context, GLint n)
4005{
4006 if (n < 0)
4007 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004008 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004009 return false;
4010 }
4011 return true;
4012}
4013
Jamie Madill5b772312018-03-08 20:28:32 -05004014bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004015{
4016 if (!context->getExtensions().robustClientMemory)
4017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004018 context->handleError(InvalidOperation()
4019 << "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004020 return false;
4021 }
4022
4023 if (bufSize < 0)
4024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004025 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004026 return false;
4027 }
4028
4029 return true;
4030}
4031
Jamie Madill5b772312018-03-08 20:28:32 -05004032bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004033{
4034 if (bufSize < numParams)
4035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004036 context->handleError(InvalidOperation() << numParams << " parameters are required but "
4037 << bufSize << " were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004038 return false;
4039 }
4040
4041 return true;
4042}
4043
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004044bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004045 GLenum target,
4046 GLenum attachment,
4047 GLenum pname,
4048 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004049{
Geoff Lange8afa902017-09-27 15:00:43 -04004050 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004051 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004052 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004053 return false;
4054 }
4055
4056 int clientVersion = context->getClientMajorVersion();
4057
4058 switch (pname)
4059 {
4060 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4061 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4062 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4063 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4064 break;
4065
Martin Radeve5285d22017-07-14 16:23:53 +03004066 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4067 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4068 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4069 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4070 if (clientVersion < 3 || !context->getExtensions().multiview)
4071 {
4072 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
4073 return false;
4074 }
4075 break;
4076
Geoff Langff5b2d52016-09-07 11:32:23 -04004077 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4078 if (clientVersion < 3 && !context->getExtensions().sRGB)
4079 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004080 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004081 return false;
4082 }
4083 break;
4084
4085 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4086 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4087 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4088 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4089 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4090 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4091 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4092 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4093 if (clientVersion < 3)
4094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004095 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004096 return false;
4097 }
4098 break;
4099
Jiawei Shaoa8802472018-05-28 11:17:47 +08004100 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4101 if (!context->getExtensions().geometryShader)
4102 {
4103 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
4104 return false;
4105 }
4106 break;
4107
Geoff Langff5b2d52016-09-07 11:32:23 -04004108 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004109 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004110 return false;
4111 }
4112
4113 // Determine if the attachment is a valid enum
4114 switch (attachment)
4115 {
4116 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004117 case GL_DEPTH:
4118 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004119 if (clientVersion < 3)
4120 {
Geoff Langfa125c92017-10-24 13:01:46 -04004121 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004122 return false;
4123 }
4124 break;
4125
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004126 case GL_DEPTH_STENCIL_ATTACHMENT:
4127 if (clientVersion < 3 && !context->isWebGL1())
4128 {
4129 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
4130 return false;
4131 }
4132 break;
4133
Geoff Langfa125c92017-10-24 13:01:46 -04004134 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004135 case GL_DEPTH_ATTACHMENT:
4136 case GL_STENCIL_ATTACHMENT:
4137 break;
4138
4139 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004140 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4141 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004142 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4143 {
Geoff Langfa125c92017-10-24 13:01:46 -04004144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004145 return false;
4146 }
4147 break;
4148 }
4149
4150 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4151 ASSERT(framebuffer);
4152
4153 if (framebuffer->id() == 0)
4154 {
4155 if (clientVersion < 3)
4156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004158 return false;
4159 }
4160
4161 switch (attachment)
4162 {
4163 case GL_BACK:
4164 case GL_DEPTH:
4165 case GL_STENCIL:
4166 break;
4167
4168 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004169 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004170 return false;
4171 }
4172 }
4173 else
4174 {
4175 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4176 {
4177 // Valid attachment query
4178 }
4179 else
4180 {
4181 switch (attachment)
4182 {
4183 case GL_DEPTH_ATTACHMENT:
4184 case GL_STENCIL_ATTACHMENT:
4185 break;
4186
4187 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004188 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004190 context->handleError(InvalidOperation());
Geoff Langff5b2d52016-09-07 11:32:23 -04004191 return false;
4192 }
4193 break;
4194
4195 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004196 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004197 return false;
4198 }
4199 }
4200 }
4201
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004202 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004203 if (attachmentObject)
4204 {
4205 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4206 attachmentObject->type() == GL_TEXTURE ||
4207 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4208
4209 switch (pname)
4210 {
4211 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4212 if (attachmentObject->type() != GL_RENDERBUFFER &&
4213 attachmentObject->type() != GL_TEXTURE)
4214 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004215 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004216 return false;
4217 }
4218 break;
4219
4220 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4221 if (attachmentObject->type() != GL_TEXTURE)
4222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004223 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004224 return false;
4225 }
4226 break;
4227
4228 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4229 if (attachmentObject->type() != GL_TEXTURE)
4230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004232 return false;
4233 }
4234 break;
4235
4236 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4237 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4238 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004239 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004240 return false;
4241 }
4242 break;
4243
4244 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4245 if (attachmentObject->type() != GL_TEXTURE)
4246 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004247 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004248 return false;
4249 }
4250 break;
4251
4252 default:
4253 break;
4254 }
4255 }
4256 else
4257 {
4258 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4259 // is NONE, then querying any other pname will generate INVALID_ENUM.
4260
4261 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4262 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4263 // INVALID_OPERATION for all other pnames
4264
4265 switch (pname)
4266 {
4267 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4268 break;
4269
4270 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4271 if (clientVersion < 3)
4272 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004273 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004274 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004275 return false;
4276 }
4277 break;
4278
4279 default:
4280 if (clientVersion < 3)
4281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004282 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004283 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004284 return false;
4285 }
4286 else
4287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004288 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004289 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004290 return false;
4291 }
4292 }
4293 }
4294
Martin Radeve5285d22017-07-14 16:23:53 +03004295 if (numParams)
4296 {
4297 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4298 {
4299 // Only when the viewport offsets are queried we can have a varying number of output
4300 // parameters.
4301 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4302 *numParams = numViews * 2;
4303 }
4304 else
4305 {
4306 // For all other queries we can have only one output parameter.
4307 *numParams = 1;
4308 }
4309 }
4310
Geoff Langff5b2d52016-09-07 11:32:23 -04004311 return true;
4312}
4313
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004314bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004315 GLenum target,
4316 GLenum attachment,
4317 GLenum pname,
4318 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004319 GLsizei *length,
4320 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004321{
4322 if (!ValidateRobustEntryPoint(context, bufSize))
4323 {
4324 return false;
4325 }
4326
Brandon Jonesd1049182018-03-28 10:02:20 -07004327 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004328 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004329 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004330 {
4331 return false;
4332 }
4333
Brandon Jonesd1049182018-03-28 10:02:20 -07004334 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004335 {
4336 return false;
4337 }
4338
Brandon Jonesd1049182018-03-28 10:02:20 -07004339 SetRobustLengthParam(length, numParams);
4340
Geoff Langff5b2d52016-09-07 11:32:23 -04004341 return true;
4342}
4343
Jamie Madill5b772312018-03-08 20:28:32 -05004344bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004345 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004346 GLenum pname,
4347 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004348 GLsizei *length,
4349 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004350{
4351 if (!ValidateRobustEntryPoint(context, bufSize))
4352 {
4353 return false;
4354 }
4355
Brandon Jonesd1049182018-03-28 10:02:20 -07004356 GLsizei numParams = 0;
4357
4358 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004359 {
4360 return false;
4361 }
4362
Brandon Jonesd1049182018-03-28 10:02:20 -07004363 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004364 {
4365 return false;
4366 }
4367
Brandon Jonesd1049182018-03-28 10:02:20 -07004368 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004369 return true;
4370}
4371
Jamie Madill5b772312018-03-08 20:28:32 -05004372bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004373 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004374 GLenum pname,
4375 GLsizei bufSize,
4376 GLsizei *length,
4377 GLint64 *params)
4378{
Brandon Jonesd1049182018-03-28 10:02:20 -07004379 GLsizei numParams = 0;
4380
Geoff Langebebe1c2016-10-14 12:01:31 -04004381 if (!ValidateRobustEntryPoint(context, bufSize))
4382 {
4383 return false;
4384 }
4385
Brandon Jonesd1049182018-03-28 10:02:20 -07004386 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004387 {
4388 return false;
4389 }
4390
Brandon Jonesd1049182018-03-28 10:02:20 -07004391 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004392 {
4393 return false;
4394 }
4395
Brandon Jonesd1049182018-03-28 10:02:20 -07004396 SetRobustLengthParam(length, numParams);
4397
Geoff Langff5b2d52016-09-07 11:32:23 -04004398 return true;
4399}
4400
Jamie Madill5b772312018-03-08 20:28:32 -05004401bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004402{
4403 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004404 if (numParams)
4405 {
4406 *numParams = 1;
4407 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004408
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004409 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4410 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4411 ? GetValidProgramNoResolve(context, program)
4412 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004413 if (!programObject)
4414 {
4415 return false;
4416 }
4417
4418 switch (pname)
4419 {
4420 case GL_DELETE_STATUS:
4421 case GL_LINK_STATUS:
4422 case GL_VALIDATE_STATUS:
4423 case GL_INFO_LOG_LENGTH:
4424 case GL_ATTACHED_SHADERS:
4425 case GL_ACTIVE_ATTRIBUTES:
4426 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4427 case GL_ACTIVE_UNIFORMS:
4428 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4429 break;
4430
4431 case GL_PROGRAM_BINARY_LENGTH:
4432 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004434 context->handleError(InvalidEnum() << "Querying GL_PROGRAM_BINARY_LENGTH "
4435 "requires GL_OES_get_program_binary or "
4436 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004437 return false;
4438 }
4439 break;
4440
4441 case GL_ACTIVE_UNIFORM_BLOCKS:
4442 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4443 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4444 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4445 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4446 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4447 if (context->getClientMajorVersion() < 3)
4448 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004449 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004450 return false;
4451 }
4452 break;
4453
Yunchao He61afff12017-03-14 15:34:03 +08004454 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004455 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004456 if (context->getClientVersion() < Version(3, 1))
4457 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004458 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004459 return false;
4460 }
4461 break;
4462
Jiawei Shao6ae51612018-02-23 14:03:25 +08004463 case GL_COMPUTE_WORK_GROUP_SIZE:
4464 if (context->getClientVersion() < Version(3, 1))
4465 {
4466 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
4467 return false;
4468 }
4469
4470 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4471 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4472 // program which has not been linked successfully, or which does not contain objects to
4473 // form a compute shader.
4474 if (!programObject->isLinked())
4475 {
4476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
4477 return false;
4478 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004479 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004480 {
4481 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveComputeShaderStage);
4482 return false;
4483 }
4484 break;
4485
Jiawei Shao447bfac2018-03-14 14:23:40 +08004486 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4487 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4488 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4489 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4490 if (!context->getExtensions().geometryShader)
4491 {
4492 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
4493 return false;
4494 }
4495
4496 // [EXT_geometry_shader] Chapter 7.12
4497 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4498 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4499 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4500 // successfully, or which does not contain objects to form a geometry shader.
4501 if (!programObject->isLinked())
4502 {
4503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
4504 return false;
4505 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004506 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004507 {
4508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveGeometryShaderStage);
4509 return false;
4510 }
4511 break;
4512
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004513 case GL_COMPLETION_STATUS_KHR:
4514 if (!context->getExtensions().parallelShaderCompile)
4515 {
4516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
4517 return false;
4518 }
4519 break;
4520
Geoff Langff5b2d52016-09-07 11:32:23 -04004521 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004522 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004523 return false;
4524 }
4525
4526 return true;
4527}
4528
4529bool ValidateGetProgramivRobustANGLE(Context *context,
4530 GLuint program,
4531 GLenum pname,
4532 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004533 GLsizei *length,
4534 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004535{
4536 if (!ValidateRobustEntryPoint(context, bufSize))
4537 {
4538 return false;
4539 }
4540
Brandon Jonesd1049182018-03-28 10:02:20 -07004541 GLsizei numParams = 0;
4542
4543 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004544 {
4545 return false;
4546 }
4547
Brandon Jonesd1049182018-03-28 10:02:20 -07004548 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004549 {
4550 return false;
4551 }
4552
Brandon Jonesd1049182018-03-28 10:02:20 -07004553 SetRobustLengthParam(length, numParams);
4554
Geoff Langff5b2d52016-09-07 11:32:23 -04004555 return true;
4556}
4557
Geoff Lang740d9022016-10-07 11:20:52 -04004558bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4559 GLenum target,
4560 GLenum pname,
4561 GLsizei bufSize,
4562 GLsizei *length,
4563 GLint *params)
4564{
4565 if (!ValidateRobustEntryPoint(context, bufSize))
4566 {
4567 return false;
4568 }
4569
Brandon Jonesd1049182018-03-28 10:02:20 -07004570 GLsizei numParams = 0;
4571
4572 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004573 {
4574 return false;
4575 }
4576
Brandon Jonesd1049182018-03-28 10:02:20 -07004577 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004578 {
4579 return false;
4580 }
4581
Brandon Jonesd1049182018-03-28 10:02:20 -07004582 SetRobustLengthParam(length, numParams);
4583
Geoff Lang740d9022016-10-07 11:20:52 -04004584 return true;
4585}
4586
Geoff Langd7d0ed32016-10-07 11:33:51 -04004587bool ValidateGetShaderivRobustANGLE(Context *context,
4588 GLuint shader,
4589 GLenum pname,
4590 GLsizei bufSize,
4591 GLsizei *length,
4592 GLint *params)
4593{
4594 if (!ValidateRobustEntryPoint(context, bufSize))
4595 {
4596 return false;
4597 }
4598
Brandon Jonesd1049182018-03-28 10:02:20 -07004599 GLsizei numParams = 0;
4600
4601 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004602 {
4603 return false;
4604 }
4605
Brandon Jonesd1049182018-03-28 10:02:20 -07004606 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004607 {
4608 return false;
4609 }
4610
Brandon Jonesd1049182018-03-28 10:02:20 -07004611 SetRobustLengthParam(length, numParams);
4612
Geoff Langd7d0ed32016-10-07 11:33:51 -04004613 return true;
4614}
4615
Geoff Langc1984ed2016-10-07 12:41:00 -04004616bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004617 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004618 GLenum pname,
4619 GLsizei bufSize,
4620 GLsizei *length,
4621 GLfloat *params)
4622{
4623 if (!ValidateRobustEntryPoint(context, bufSize))
4624 {
4625 return false;
4626 }
4627
Brandon Jonesd1049182018-03-28 10:02:20 -07004628 GLsizei numParams = 0;
4629
4630 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004631 {
4632 return false;
4633 }
4634
Brandon Jonesd1049182018-03-28 10:02:20 -07004635 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004636 {
4637 return false;
4638 }
4639
Brandon Jonesd1049182018-03-28 10:02:20 -07004640 SetRobustLengthParam(length, numParams);
4641
Geoff Langc1984ed2016-10-07 12:41:00 -04004642 return true;
4643}
4644
Geoff Langc1984ed2016-10-07 12:41:00 -04004645bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004646 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004647 GLenum pname,
4648 GLsizei bufSize,
4649 GLsizei *length,
4650 GLint *params)
4651{
Brandon Jonesd1049182018-03-28 10:02:20 -07004652
Geoff Langc1984ed2016-10-07 12:41:00 -04004653 if (!ValidateRobustEntryPoint(context, bufSize))
4654 {
4655 return false;
4656 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004657 GLsizei numParams = 0;
4658 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004659 {
4660 return false;
4661 }
4662
Brandon Jonesd1049182018-03-28 10:02:20 -07004663 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004664 {
4665 return false;
4666 }
4667
Brandon Jonesd1049182018-03-28 10:02:20 -07004668 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004669 return true;
4670}
4671
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004672bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4673 TextureType target,
4674 GLenum pname,
4675 GLsizei bufSize,
4676 GLsizei *length,
4677 GLint *params)
4678{
4679 UNIMPLEMENTED();
4680 return false;
4681}
4682
4683bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4684 TextureType target,
4685 GLenum pname,
4686 GLsizei bufSize,
4687 GLsizei *length,
4688 GLuint *params)
4689{
4690 UNIMPLEMENTED();
4691 return false;
4692}
4693
Geoff Langc1984ed2016-10-07 12:41:00 -04004694bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004695 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004696 GLenum pname,
4697 GLsizei bufSize,
4698 const GLfloat *params)
4699{
4700 if (!ValidateRobustEntryPoint(context, bufSize))
4701 {
4702 return false;
4703 }
4704
4705 return ValidateTexParameterBase(context, target, pname, bufSize, params);
4706}
4707
Geoff Langc1984ed2016-10-07 12:41:00 -04004708bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004709 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004710 GLenum pname,
4711 GLsizei bufSize,
4712 const GLint *params)
4713{
4714 if (!ValidateRobustEntryPoint(context, bufSize))
4715 {
4716 return false;
4717 }
4718
4719 return ValidateTexParameterBase(context, target, pname, bufSize, params);
4720}
4721
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004722bool ValidateTexParameterIivRobustANGLE(Context *context,
4723 TextureType target,
4724 GLenum pname,
4725 GLsizei bufSize,
4726 const GLint *params)
4727{
4728 UNIMPLEMENTED();
4729 return false;
4730}
4731
4732bool ValidateTexParameterIuivRobustANGLE(Context *context,
4733 TextureType target,
4734 GLenum pname,
4735 GLsizei bufSize,
4736 const GLuint *params)
4737{
4738 UNIMPLEMENTED();
4739 return false;
4740}
4741
Geoff Langc1984ed2016-10-07 12:41:00 -04004742bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4743 GLuint sampler,
4744 GLenum pname,
4745 GLuint bufSize,
4746 GLsizei *length,
4747 GLfloat *params)
4748{
4749 if (!ValidateRobustEntryPoint(context, bufSize))
4750 {
4751 return false;
4752 }
4753
Brandon Jonesd1049182018-03-28 10:02:20 -07004754 GLsizei numParams = 0;
4755
4756 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004757 {
4758 return false;
4759 }
4760
Brandon Jonesd1049182018-03-28 10:02:20 -07004761 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004762 {
4763 return false;
4764 }
4765
Brandon Jonesd1049182018-03-28 10:02:20 -07004766 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004767 return true;
4768}
4769
Geoff Langc1984ed2016-10-07 12:41:00 -04004770bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4771 GLuint sampler,
4772 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004773 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004774 GLsizei *length,
4775 GLint *params)
4776{
4777 if (!ValidateRobustEntryPoint(context, bufSize))
4778 {
4779 return false;
4780 }
4781
Brandon Jonesd1049182018-03-28 10:02:20 -07004782 GLsizei numParams = 0;
4783
4784 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004785 {
4786 return false;
4787 }
4788
Brandon Jonesd1049182018-03-28 10:02:20 -07004789 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004790 {
4791 return false;
4792 }
4793
Brandon Jonesd1049182018-03-28 10:02:20 -07004794 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004795 return true;
4796}
4797
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004798bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4799 GLuint sampler,
4800 GLenum pname,
4801 GLsizei bufSize,
4802 GLsizei *length,
4803 GLint *params)
4804{
4805 UNIMPLEMENTED();
4806 return false;
4807}
4808
4809bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4810 GLuint sampler,
4811 GLenum pname,
4812 GLsizei bufSize,
4813 GLsizei *length,
4814 GLuint *params)
4815{
4816 UNIMPLEMENTED();
4817 return false;
4818}
4819
Geoff Langc1984ed2016-10-07 12:41:00 -04004820bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4821 GLuint sampler,
4822 GLenum pname,
4823 GLsizei bufSize,
4824 const GLfloat *params)
4825{
4826 if (!ValidateRobustEntryPoint(context, bufSize))
4827 {
4828 return false;
4829 }
4830
4831 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
4832}
4833
Geoff Langc1984ed2016-10-07 12:41:00 -04004834bool ValidateSamplerParameterivRobustANGLE(Context *context,
4835 GLuint sampler,
4836 GLenum pname,
4837 GLsizei bufSize,
4838 const GLint *params)
4839{
4840 if (!ValidateRobustEntryPoint(context, bufSize))
4841 {
4842 return false;
4843 }
4844
4845 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, params);
4846}
4847
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004848bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4849 GLuint sampler,
4850 GLenum pname,
4851 GLsizei bufSize,
4852 const GLint *param)
4853{
4854 UNIMPLEMENTED();
4855 return false;
4856}
4857
4858bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4859 GLuint sampler,
4860 GLenum pname,
4861 GLsizei bufSize,
4862 const GLuint *param)
4863{
4864 UNIMPLEMENTED();
4865 return false;
4866}
4867
Geoff Lang0b031062016-10-13 14:30:04 -04004868bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4869 GLuint index,
4870 GLenum pname,
4871 GLsizei bufSize,
4872 GLsizei *length,
4873 GLfloat *params)
4874{
4875 if (!ValidateRobustEntryPoint(context, bufSize))
4876 {
4877 return false;
4878 }
4879
Brandon Jonesd1049182018-03-28 10:02:20 -07004880 GLsizei writeLength = 0;
4881
4882 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004883 {
4884 return false;
4885 }
4886
Brandon Jonesd1049182018-03-28 10:02:20 -07004887 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004888 {
4889 return false;
4890 }
4891
Brandon Jonesd1049182018-03-28 10:02:20 -07004892 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004893 return true;
4894}
4895
Geoff Lang0b031062016-10-13 14:30:04 -04004896bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4897 GLuint index,
4898 GLenum pname,
4899 GLsizei bufSize,
4900 GLsizei *length,
4901 GLint *params)
4902{
4903 if (!ValidateRobustEntryPoint(context, bufSize))
4904 {
4905 return false;
4906 }
4907
Brandon Jonesd1049182018-03-28 10:02:20 -07004908 GLsizei writeLength = 0;
4909
4910 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004911 {
4912 return false;
4913 }
4914
Brandon Jonesd1049182018-03-28 10:02:20 -07004915 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004916 {
4917 return false;
4918 }
4919
Brandon Jonesd1049182018-03-28 10:02:20 -07004920 SetRobustLengthParam(length, writeLength);
4921
Geoff Lang0b031062016-10-13 14:30:04 -04004922 return true;
4923}
4924
Geoff Lang0b031062016-10-13 14:30:04 -04004925bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4926 GLuint index,
4927 GLenum pname,
4928 GLsizei bufSize,
4929 GLsizei *length,
4930 void **pointer)
4931{
4932 if (!ValidateRobustEntryPoint(context, bufSize))
4933 {
4934 return false;
4935 }
4936
Brandon Jonesd1049182018-03-28 10:02:20 -07004937 GLsizei writeLength = 0;
4938
4939 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004940 {
4941 return false;
4942 }
4943
Brandon Jonesd1049182018-03-28 10:02:20 -07004944 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004945 {
4946 return false;
4947 }
4948
Brandon Jonesd1049182018-03-28 10:02:20 -07004949 SetRobustLengthParam(length, writeLength);
4950
Geoff Lang0b031062016-10-13 14:30:04 -04004951 return true;
4952}
4953
Geoff Lang0b031062016-10-13 14:30:04 -04004954bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4955 GLuint index,
4956 GLenum pname,
4957 GLsizei bufSize,
4958 GLsizei *length,
4959 GLint *params)
4960{
4961 if (!ValidateRobustEntryPoint(context, bufSize))
4962 {
4963 return false;
4964 }
4965
Brandon Jonesd1049182018-03-28 10:02:20 -07004966 GLsizei writeLength = 0;
4967
4968 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004969 {
4970 return false;
4971 }
4972
Brandon Jonesd1049182018-03-28 10:02:20 -07004973 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004974 {
4975 return false;
4976 }
4977
Brandon Jonesd1049182018-03-28 10:02:20 -07004978 SetRobustLengthParam(length, writeLength);
4979
Geoff Lang0b031062016-10-13 14:30:04 -04004980 return true;
4981}
4982
Geoff Lang0b031062016-10-13 14:30:04 -04004983bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
4984 GLuint index,
4985 GLenum pname,
4986 GLsizei bufSize,
4987 GLsizei *length,
4988 GLuint *params)
4989{
4990 if (!ValidateRobustEntryPoint(context, bufSize))
4991 {
4992 return false;
4993 }
4994
Brandon Jonesd1049182018-03-28 10:02:20 -07004995 GLsizei writeLength = 0;
4996
4997 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004998 {
4999 return false;
5000 }
5001
Brandon Jonesd1049182018-03-28 10:02:20 -07005002 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04005003 {
5004 return false;
5005 }
5006
Brandon Jonesd1049182018-03-28 10:02:20 -07005007 SetRobustLengthParam(length, writeLength);
5008
Geoff Lang0b031062016-10-13 14:30:04 -04005009 return true;
5010}
5011
Geoff Lang6899b872016-10-14 11:30:13 -04005012bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5013 GLuint program,
5014 GLuint uniformBlockIndex,
5015 GLenum pname,
5016 GLsizei bufSize,
5017 GLsizei *length,
5018 GLint *params)
5019{
5020 if (!ValidateRobustEntryPoint(context, bufSize))
5021 {
5022 return false;
5023 }
5024
Brandon Jonesd1049182018-03-28 10:02:20 -07005025 GLsizei writeLength = 0;
5026
5027 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5028 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005029 {
5030 return false;
5031 }
5032
Brandon Jonesd1049182018-03-28 10:02:20 -07005033 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005034 {
5035 return false;
5036 }
5037
Brandon Jonesd1049182018-03-28 10:02:20 -07005038 SetRobustLengthParam(length, writeLength);
5039
Geoff Lang6899b872016-10-14 11:30:13 -04005040 return true;
5041}
5042
Brandon Jones416aaf92018-04-10 08:10:16 -07005043bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005044 GLenum target,
5045 GLenum internalformat,
5046 GLenum pname,
5047 GLsizei bufSize,
5048 GLsizei *length,
5049 GLint *params)
5050{
5051 if (!ValidateRobustEntryPoint(context, bufSize))
5052 {
5053 return false;
5054 }
5055
Brandon Jonesd1049182018-03-28 10:02:20 -07005056 GLsizei numParams = 0;
5057
5058 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5059 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005060 {
5061 return false;
5062 }
5063
Brandon Jonesd1049182018-03-28 10:02:20 -07005064 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005065 {
5066 return false;
5067 }
5068
Brandon Jonesd1049182018-03-28 10:02:20 -07005069 SetRobustLengthParam(length, numParams);
5070
Geoff Lang0a9661f2016-10-20 10:59:20 -07005071 return true;
5072}
5073
Jamie Madill5b772312018-03-08 20:28:32 -05005074bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005075 GLuint attribIndex,
5076 GLint size,
5077 GLenum type,
5078 GLboolean pureInteger)
5079{
5080 const Caps &caps = context->getCaps();
5081 if (attribIndex >= caps.maxVertexAttributes)
5082 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005083 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005084 return false;
5085 }
5086
5087 if (size < 1 || size > 4)
5088 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005089 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005090 return false;
Shao80957d92017-02-20 21:25:59 +08005091 }
5092
5093 switch (type)
5094 {
5095 case GL_BYTE:
5096 case GL_UNSIGNED_BYTE:
5097 case GL_SHORT:
5098 case GL_UNSIGNED_SHORT:
5099 break;
5100
5101 case GL_INT:
5102 case GL_UNSIGNED_INT:
5103 if (context->getClientMajorVersion() < 3)
5104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005105 context->handleError(InvalidEnum()
5106 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005107 return false;
5108 }
5109 break;
5110
5111 case GL_FIXED:
5112 case GL_FLOAT:
5113 if (pureInteger)
5114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005115 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005116 return false;
5117 }
5118 break;
5119
5120 case GL_HALF_FLOAT:
5121 if (context->getClientMajorVersion() < 3)
5122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005123 context->handleError(InvalidEnum()
5124 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005125 return false;
5126 }
5127 if (pureInteger)
5128 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005129 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005130 return false;
5131 }
5132 break;
5133
5134 case GL_INT_2_10_10_10_REV:
5135 case GL_UNSIGNED_INT_2_10_10_10_REV:
5136 if (context->getClientMajorVersion() < 3)
5137 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005138 context->handleError(InvalidEnum()
5139 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005140 return false;
5141 }
5142 if (pureInteger)
5143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005145 return false;
5146 }
5147 if (size != 4)
5148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005149 context->handleError(InvalidOperation() << "Type is INT_2_10_10_10_REV or "
5150 "UNSIGNED_INT_2_10_10_10_REV and "
5151 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005152 return false;
5153 }
5154 break;
5155
5156 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005157 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
Shao80957d92017-02-20 21:25:59 +08005158 return false;
5159 }
5160
5161 return true;
5162}
5163
Geoff Lang76e65652017-03-27 14:58:02 -04005164// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5165// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5166// specified clear value and the type of a buffer that is being cleared generates an
5167// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005168bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005169 GLint drawbuffer,
5170 const GLenum *validComponentTypes,
5171 size_t validComponentTypeCount)
5172{
5173 const FramebufferAttachment *attachment =
5174 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5175 if (attachment)
5176 {
5177 GLenum componentType = attachment->getFormat().info->componentType;
5178 const GLenum *end = validComponentTypes + validComponentTypeCount;
5179 if (std::find(validComponentTypes, end, componentType) == end)
5180 {
5181 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005182 InvalidOperation()
5183 << "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005184 return false;
5185 }
5186 }
5187
5188 return true;
5189}
5190
Jamie Madill5b772312018-03-08 20:28:32 -05005191bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005192{
5193 if (!ValidateRobustEntryPoint(context, dataSize))
5194 {
5195 return false;
5196 }
5197
Jamie Madill43da7c42018-08-01 11:34:49 -04005198 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005199 if (pixelUnpackBuffer == nullptr)
5200 {
5201 if (dataSize < imageSize)
5202 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005203 context->handleError(InvalidOperation() << "dataSize must be at least " << imageSize);
Corentin Wallezb2931602017-04-11 15:58:57 -04005204 }
5205 }
5206 return true;
5207}
5208
Jamie Madill5b772312018-03-08 20:28:32 -05005209bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005210 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005211 GLenum pname,
5212 bool pointerVersion,
5213 GLsizei *numParams)
5214{
5215 if (numParams)
5216 {
5217 *numParams = 0;
5218 }
5219
Corentin Walleze4477002017-12-01 14:39:58 -05005220 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005223 return false;
5224 }
5225
5226 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5227 if (!buffer)
5228 {
5229 // A null buffer means that "0" is bound to the requested buffer target
Brandon Jones6cad5662017-06-14 13:25:13 -07005230 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005231 return false;
5232 }
5233
5234 const Extensions &extensions = context->getExtensions();
5235
5236 switch (pname)
5237 {
5238 case GL_BUFFER_USAGE:
5239 case GL_BUFFER_SIZE:
5240 break;
5241
5242 case GL_BUFFER_ACCESS_OES:
5243 if (!extensions.mapBuffer)
5244 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005245 context->handleError(InvalidEnum()
5246 << "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005247 return false;
5248 }
5249 break;
5250
5251 case GL_BUFFER_MAPPED:
5252 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5253 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5254 !extensions.mapBufferRange)
5255 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005256 context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0, "
5257 "GL_OES_mapbuffer or "
5258 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005259 return false;
5260 }
5261 break;
5262
5263 case GL_BUFFER_MAP_POINTER:
5264 if (!pointerVersion)
5265 {
5266 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005267 InvalidEnum()
5268 << "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005269 return false;
5270 }
5271 break;
5272
5273 case GL_BUFFER_ACCESS_FLAGS:
5274 case GL_BUFFER_MAP_OFFSET:
5275 case GL_BUFFER_MAP_LENGTH:
5276 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005278 context->handleError(InvalidEnum()
5279 << "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005280 return false;
5281 }
5282 break;
5283
Geoff Lang79b91402018-10-04 15:11:30 -04005284 case GL_MEMORY_SIZE_ANGLE:
5285 if (!context->getExtensions().memorySize)
5286 {
5287 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5288 return false;
5289 }
5290 break;
5291
Jamie Madillbe849e42017-05-02 15:49:00 -04005292 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005293 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005294 return false;
5295 }
5296
5297 // All buffer parameter queries return one value.
5298 if (numParams)
5299 {
5300 *numParams = 1;
5301 }
5302
5303 return true;
5304}
5305
5306bool ValidateGetRenderbufferParameterivBase(Context *context,
5307 GLenum target,
5308 GLenum pname,
5309 GLsizei *length)
5310{
5311 if (length)
5312 {
5313 *length = 0;
5314 }
5315
5316 if (target != GL_RENDERBUFFER)
5317 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005318 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005319 return false;
5320 }
5321
5322 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5323 if (renderbuffer == nullptr)
5324 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005325 ANGLE_VALIDATION_ERR(context, InvalidOperation(), RenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005326 return false;
5327 }
5328
5329 switch (pname)
5330 {
5331 case GL_RENDERBUFFER_WIDTH:
5332 case GL_RENDERBUFFER_HEIGHT:
5333 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5334 case GL_RENDERBUFFER_RED_SIZE:
5335 case GL_RENDERBUFFER_GREEN_SIZE:
5336 case GL_RENDERBUFFER_BLUE_SIZE:
5337 case GL_RENDERBUFFER_ALPHA_SIZE:
5338 case GL_RENDERBUFFER_DEPTH_SIZE:
5339 case GL_RENDERBUFFER_STENCIL_SIZE:
5340 break;
5341
5342 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5343 if (!context->getExtensions().framebufferMultisample)
5344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005345 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005346 return false;
5347 }
5348 break;
5349
Geoff Lang79b91402018-10-04 15:11:30 -04005350 case GL_MEMORY_SIZE_ANGLE:
5351 if (!context->getExtensions().memorySize)
5352 {
5353 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5354 return false;
5355 }
5356 break;
5357
Jamie Madillbe849e42017-05-02 15:49:00 -04005358 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005359 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005360 return false;
5361 }
5362
5363 if (length)
5364 {
5365 *length = 1;
5366 }
5367 return true;
5368}
5369
5370bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5371{
5372 if (length)
5373 {
5374 *length = 0;
5375 }
5376
5377 if (GetValidShader(context, shader) == nullptr)
5378 {
5379 return false;
5380 }
5381
5382 switch (pname)
5383 {
5384 case GL_SHADER_TYPE:
5385 case GL_DELETE_STATUS:
5386 case GL_COMPILE_STATUS:
5387 case GL_INFO_LOG_LENGTH:
5388 case GL_SHADER_SOURCE_LENGTH:
5389 break;
5390
5391 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5392 if (!context->getExtensions().translatedShaderSource)
5393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005394 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005395 return false;
5396 }
5397 break;
5398
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005399 case GL_COMPLETION_STATUS_KHR:
5400 if (!context->getExtensions().parallelShaderCompile)
5401 {
5402 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
5403 return false;
5404 }
5405 break;
5406
Jamie Madillbe849e42017-05-02 15:49:00 -04005407 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005408 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005409 return false;
5410 }
5411
5412 if (length)
5413 {
5414 *length = 1;
5415 }
5416 return true;
5417}
5418
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005419bool ValidateGetTexParameterBase(Context *context,
5420 TextureType target,
5421 GLenum pname,
5422 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005423{
5424 if (length)
5425 {
5426 *length = 0;
5427 }
5428
5429 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5430 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005431 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005432 return false;
5433 }
5434
5435 if (context->getTargetTexture(target) == nullptr)
5436 {
5437 // Should only be possible for external textures
Brandon Jones6cad5662017-06-14 13:25:13 -07005438 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005439 return false;
5440 }
5441
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005442 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5443 {
5444 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5445 return false;
5446 }
5447
Jamie Madillbe849e42017-05-02 15:49:00 -04005448 switch (pname)
5449 {
5450 case GL_TEXTURE_MAG_FILTER:
5451 case GL_TEXTURE_MIN_FILTER:
5452 case GL_TEXTURE_WRAP_S:
5453 case GL_TEXTURE_WRAP_T:
5454 break;
5455
5456 case GL_TEXTURE_USAGE_ANGLE:
5457 if (!context->getExtensions().textureUsage)
5458 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005459 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005460 return false;
5461 }
5462 break;
5463
5464 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005465 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005466 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005467 return false;
5468 }
5469 break;
5470
5471 case GL_TEXTURE_IMMUTABLE_FORMAT:
5472 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5473 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005475 return false;
5476 }
5477 break;
5478
5479 case GL_TEXTURE_WRAP_R:
5480 case GL_TEXTURE_IMMUTABLE_LEVELS:
5481 case GL_TEXTURE_SWIZZLE_R:
5482 case GL_TEXTURE_SWIZZLE_G:
5483 case GL_TEXTURE_SWIZZLE_B:
5484 case GL_TEXTURE_SWIZZLE_A:
5485 case GL_TEXTURE_BASE_LEVEL:
5486 case GL_TEXTURE_MAX_LEVEL:
5487 case GL_TEXTURE_MIN_LOD:
5488 case GL_TEXTURE_MAX_LOD:
5489 case GL_TEXTURE_COMPARE_MODE:
5490 case GL_TEXTURE_COMPARE_FUNC:
5491 if (context->getClientMajorVersion() < 3)
5492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005493 context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005494 return false;
5495 }
5496 break;
5497
5498 case GL_TEXTURE_SRGB_DECODE_EXT:
5499 if (!context->getExtensions().textureSRGBDecode)
5500 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005501 context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005502 return false;
5503 }
5504 break;
5505
Yunchao Hebacaa712018-01-30 14:01:39 +08005506 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5507 if (context->getClientVersion() < Version(3, 1))
5508 {
5509 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
5510 return false;
5511 }
5512 break;
5513
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005514 case GL_GENERATE_MIPMAP:
5515 case GL_TEXTURE_CROP_RECT_OES:
5516 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5517 // after GL_OES_draw_texture functionality implemented
5518 if (context->getClientMajorVersion() > 1)
5519 {
5520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
5521 return false;
5522 }
5523 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005524
5525 case GL_MEMORY_SIZE_ANGLE:
5526 if (!context->getExtensions().memorySize)
5527 {
5528 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5529 return false;
5530 }
5531 break;
5532
Jamie Madillbe849e42017-05-02 15:49:00 -04005533 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005534 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005535 return false;
5536 }
5537
5538 if (length)
5539 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005540 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005541 }
5542 return true;
5543}
5544
5545bool ValidateGetVertexAttribBase(Context *context,
5546 GLuint index,
5547 GLenum pname,
5548 GLsizei *length,
5549 bool pointer,
5550 bool pureIntegerEntryPoint)
5551{
5552 if (length)
5553 {
5554 *length = 0;
5555 }
5556
5557 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5558 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005559 context->handleError(InvalidOperation() << "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005560 return false;
5561 }
5562
5563 if (index >= context->getCaps().maxVertexAttributes)
5564 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005565 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005566 return false;
5567 }
5568
5569 if (pointer)
5570 {
5571 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5572 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005573 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005574 return false;
5575 }
5576 }
5577 else
5578 {
5579 switch (pname)
5580 {
5581 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5582 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5583 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5584 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5585 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5586 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5587 case GL_CURRENT_VERTEX_ATTRIB:
5588 break;
5589
5590 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5591 static_assert(
5592 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5593 "ANGLE extension enums not equal to GL enums.");
5594 if (context->getClientMajorVersion() < 3 &&
5595 !context->getExtensions().instancedArrays)
5596 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005597 context->handleError(InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5598 "requires OpenGL ES 3.0 or "
5599 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005600 return false;
5601 }
5602 break;
5603
5604 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5605 if (context->getClientMajorVersion() < 3)
5606 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005607 context->handleError(
5608 InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005609 return false;
5610 }
5611 break;
5612
5613 case GL_VERTEX_ATTRIB_BINDING:
5614 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5615 if (context->getClientVersion() < ES_3_1)
5616 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005617 context->handleError(InvalidEnum()
5618 << "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005619 return false;
5620 }
5621 break;
5622
5623 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005624 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005625 return false;
5626 }
5627 }
5628
5629 if (length)
5630 {
5631 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5632 {
5633 *length = 4;
5634 }
5635 else
5636 {
5637 *length = 1;
5638 }
5639 }
5640
5641 return true;
5642}
5643
Jamie Madill4928b7c2017-06-20 12:57:39 -04005644bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005645 GLint x,
5646 GLint y,
5647 GLsizei width,
5648 GLsizei height,
5649 GLenum format,
5650 GLenum type,
5651 GLsizei bufSize,
5652 GLsizei *length,
5653 GLsizei *columns,
5654 GLsizei *rows,
5655 void *pixels)
5656{
5657 if (length != nullptr)
5658 {
5659 *length = 0;
5660 }
5661 if (rows != nullptr)
5662 {
5663 *rows = 0;
5664 }
5665 if (columns != nullptr)
5666 {
5667 *columns = 0;
5668 }
5669
5670 if (width < 0 || height < 0)
5671 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005672 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005673 return false;
5674 }
5675
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005676 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005677
Jamie Madill427064d2018-04-13 16:20:34 -04005678 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005679 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005680 return false;
5681 }
5682
Jamie Madille98b1b52018-03-08 09:47:23 -05005683 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005684 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005685 return false;
5686 }
5687
Jamie Madill690c8eb2018-03-12 15:20:03 -04005688 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005689 ASSERT(framebuffer);
5690
5691 if (framebuffer->getReadBufferState() == GL_NONE)
5692 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005693 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005694 return false;
5695 }
5696
5697 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5698 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5699 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5700 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5701 // situation is an application error that would lead to a crash in ANGLE.
5702 if (readBuffer == nullptr)
5703 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005704 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005705 return false;
5706 }
5707
Martin Radev28031682017-07-28 14:47:56 +03005708 // ANGLE_multiview, Revision 1:
5709 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005710 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5711 // in the current read framebuffer is more than one.
5712 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005713 {
5714 context->handleError(InvalidFramebufferOperation()
5715 << "Attempting to read from a multi-view framebuffer.");
5716 return false;
5717 }
5718
Geoff Lang280ba992017-04-18 16:30:58 -04005719 if (context->getExtensions().webglCompatibility)
5720 {
5721 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5722 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5723 // and type before validating the combination of format and type. However, the
5724 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5725 // verifies that GL_INVALID_OPERATION is generated.
5726 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5727 // dEQP/WebGL.
5728 if (!ValidReadPixelsFormatEnum(context, format))
5729 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005730 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005731 return false;
5732 }
5733
5734 if (!ValidReadPixelsTypeEnum(context, type))
5735 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005736 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005737 return false;
5738 }
5739 }
5740
Jamie Madill690c8eb2018-03-12 15:20:03 -04005741 GLenum currentFormat = GL_NONE;
5742 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5743
5744 GLenum currentType = GL_NONE;
5745 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5746
Jamie Madillbe849e42017-05-02 15:49:00 -04005747 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5748
5749 bool validFormatTypeCombination =
5750 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5751
5752 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5753 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005754 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005755 return false;
5756 }
5757
5758 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005759 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005760 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5761 {
5762 // ...the buffer object's data store is currently mapped.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005763 context->handleError(InvalidOperation() << "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005764 return false;
5765 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005766 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5767 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5768 {
5769 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelPackBufferBoundForTransformFeedback);
5770 return false;
5771 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005772
5773 // .. the data would be packed to the buffer object such that the memory writes required
5774 // would exceed the data store size.
5775 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005776 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005777 const auto &pack = context->getGLState().getPackState();
5778
Jamie Madillca2ff382018-07-11 09:01:17 -04005779 GLuint endByte = 0;
5780 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005781 {
Jamie Madillca2ff382018-07-11 09:01:17 -04005782 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005783 return false;
5784 }
5785
Jamie Madillbe849e42017-05-02 15:49:00 -04005786 if (bufSize >= 0)
5787 {
5788 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5789 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005790 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005791 return false;
5792 }
5793 }
5794
5795 if (pixelPackBuffer != nullptr)
5796 {
5797 CheckedNumeric<size_t> checkedEndByte(endByte);
5798 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5799 checkedEndByte += checkedOffset;
5800
5801 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5802 {
5803 // Overflow past the end of the buffer
Brandon Jones6cad5662017-06-14 13:25:13 -07005804 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005805 return false;
5806 }
5807 }
5808
5809 if (pixelPackBuffer == nullptr && length != nullptr)
5810 {
5811 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5812 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005813 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005814 return false;
5815 }
5816
5817 *length = static_cast<GLsizei>(endByte);
5818 }
5819
Geoff Langa953b522018-02-21 16:56:23 -05005820 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005821 angle::CheckedNumeric<int> clippedExtent(length);
5822 if (start < 0)
5823 {
5824 // "subtract" the area that is less than 0
5825 clippedExtent += start;
5826 }
5827
Geoff Langa953b522018-02-21 16:56:23 -05005828 angle::CheckedNumeric<int> readExtent = start;
5829 readExtent += length;
5830 if (!readExtent.IsValid())
5831 {
5832 return false;
5833 }
5834
5835 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005836 {
5837 // Subtract the region to the right of the read buffer
5838 clippedExtent -= (readExtent - bufferSize);
5839 }
5840
5841 if (!clippedExtent.IsValid())
5842 {
Geoff Langa953b522018-02-21 16:56:23 -05005843 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005844 }
5845
Geoff Langa953b522018-02-21 16:56:23 -05005846 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5847 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005848 };
5849
Geoff Langa953b522018-02-21 16:56:23 -05005850 GLsizei writtenColumns = 0;
5851 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5852 {
5853 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
5854 return false;
5855 }
5856
5857 GLsizei writtenRows = 0;
5858 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5859 {
5860 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
5861 return false;
5862 }
5863
Jamie Madillbe849e42017-05-02 15:49:00 -04005864 if (columns != nullptr)
5865 {
Geoff Langa953b522018-02-21 16:56:23 -05005866 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005867 }
5868
5869 if (rows != nullptr)
5870 {
Geoff Langa953b522018-02-21 16:56:23 -05005871 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005872 }
5873
5874 return true;
5875}
5876
5877template <typename ParamType>
5878bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005879 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005880 GLenum pname,
5881 GLsizei bufSize,
5882 const ParamType *params)
5883{
5884 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5885 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005886 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005887 return false;
5888 }
5889
5890 if (context->getTargetTexture(target) == nullptr)
5891 {
5892 // Should only be possible for external textures
Brandon Jones6cad5662017-06-14 13:25:13 -07005893 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005894 return false;
5895 }
5896
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005897 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005898 if (bufSize >= 0 && bufSize < minBufSize)
5899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005900 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005901 return false;
5902 }
5903
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005904 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5905 {
5906 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5907 return false;
5908 }
5909
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 switch (pname)
5911 {
5912 case GL_TEXTURE_WRAP_R:
5913 case GL_TEXTURE_SWIZZLE_R:
5914 case GL_TEXTURE_SWIZZLE_G:
5915 case GL_TEXTURE_SWIZZLE_B:
5916 case GL_TEXTURE_SWIZZLE_A:
5917 case GL_TEXTURE_BASE_LEVEL:
5918 case GL_TEXTURE_MAX_LEVEL:
5919 case GL_TEXTURE_COMPARE_MODE:
5920 case GL_TEXTURE_COMPARE_FUNC:
5921 case GL_TEXTURE_MIN_LOD:
5922 case GL_TEXTURE_MAX_LOD:
5923 if (context->getClientMajorVersion() < 3)
5924 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005925 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005926 return false;
5927 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005928 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005930 context->handleError(InvalidEnum() << "ES3 texture parameters are not "
5931 "available without "
5932 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 return false;
5934 }
5935 break;
5936
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005937 case GL_GENERATE_MIPMAP:
5938 case GL_TEXTURE_CROP_RECT_OES:
5939 if (context->getClientMajorVersion() > 1)
5940 {
5941 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
5942 return false;
5943 }
5944 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005945 default:
5946 break;
5947 }
5948
Olli Etuahod310a432018-08-24 15:40:23 +03005949 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005950 {
5951 switch (pname)
5952 {
5953 case GL_TEXTURE_MIN_FILTER:
5954 case GL_TEXTURE_MAG_FILTER:
5955 case GL_TEXTURE_WRAP_S:
5956 case GL_TEXTURE_WRAP_T:
5957 case GL_TEXTURE_WRAP_R:
5958 case GL_TEXTURE_MIN_LOD:
5959 case GL_TEXTURE_MAX_LOD:
5960 case GL_TEXTURE_COMPARE_MODE:
5961 case GL_TEXTURE_COMPARE_FUNC:
5962 context->handleError(InvalidEnum()
5963 << "Invalid parameter for 2D multisampled textures.");
5964 return false;
5965 }
5966 }
5967
Jamie Madillbe849e42017-05-02 15:49:00 -04005968 switch (pname)
5969 {
5970 case GL_TEXTURE_WRAP_S:
5971 case GL_TEXTURE_WRAP_T:
5972 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005973 {
5974 bool restrictedWrapModes =
5975 target == TextureType::External || target == TextureType::Rectangle;
5976 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005978 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005979 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005980 }
5981 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005982
5983 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005984 {
5985 bool restrictedMinFilter =
5986 target == TextureType::External || target == TextureType::Rectangle;
5987 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04005988 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07005989 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005990 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07005991 }
5992 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005993
5994 case GL_TEXTURE_MAG_FILTER:
5995 if (!ValidateTextureMagFilterValue(context, params))
5996 {
5997 return false;
5998 }
5999 break;
6000
6001 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04006002 if (!context->getExtensions().textureUsage)
6003 {
6004 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6005 return false;
6006 }
6007
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 switch (ConvertToGLenum(params[0]))
6009 {
6010 case GL_NONE:
6011 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
6012 break;
6013
6014 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006016 return false;
6017 }
6018 break;
6019
6020 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006021 {
6022 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6023 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006025 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006026 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006027 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
6028 }
6029 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006030
6031 case GL_TEXTURE_MIN_LOD:
6032 case GL_TEXTURE_MAX_LOD:
6033 // any value is permissible
6034 break;
6035
6036 case GL_TEXTURE_COMPARE_MODE:
6037 if (!ValidateTextureCompareModeValue(context, params))
6038 {
6039 return false;
6040 }
6041 break;
6042
6043 case GL_TEXTURE_COMPARE_FUNC:
6044 if (!ValidateTextureCompareFuncValue(context, params))
6045 {
6046 return false;
6047 }
6048 break;
6049
6050 case GL_TEXTURE_SWIZZLE_R:
6051 case GL_TEXTURE_SWIZZLE_G:
6052 case GL_TEXTURE_SWIZZLE_B:
6053 case GL_TEXTURE_SWIZZLE_A:
6054 switch (ConvertToGLenum(params[0]))
6055 {
6056 case GL_RED:
6057 case GL_GREEN:
6058 case GL_BLUE:
6059 case GL_ALPHA:
6060 case GL_ZERO:
6061 case GL_ONE:
6062 break;
6063
6064 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006065 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006066 return false;
6067 }
6068 break;
6069
6070 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006071 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006072 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006073 context->handleError(InvalidValue() << "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 return false;
6075 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006076 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006078 context->handleError(InvalidOperation()
6079 << "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 return false;
6081 }
Olli Etuahod310a432018-08-24 15:40:23 +03006082 if ((target == TextureType::_2DMultisample ||
6083 target == TextureType::_2DMultisampleArray) &&
6084 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006085 {
6086 context->handleError(InvalidOperation()
6087 << "Base level must be 0 for multisampled textures.");
6088 return false;
6089 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006090 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006091 {
6092 context->handleError(InvalidOperation()
6093 << "Base level must be 0 for rectangle textures.");
6094 return false;
6095 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 break;
6097
6098 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006099 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006101 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006102 return false;
6103 }
6104 break;
6105
6106 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6107 if (context->getClientVersion() < Version(3, 1))
6108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006109 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 return false;
6111 }
6112 switch (ConvertToGLenum(params[0]))
6113 {
6114 case GL_DEPTH_COMPONENT:
6115 case GL_STENCIL_INDEX:
6116 break;
6117
6118 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006119 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006120 return false;
6121 }
6122 break;
6123
6124 case GL_TEXTURE_SRGB_DECODE_EXT:
6125 if (!ValidateTextureSRGBDecodeValue(context, params))
6126 {
6127 return false;
6128 }
6129 break;
6130
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006131 case GL_GENERATE_MIPMAP:
6132 case GL_TEXTURE_CROP_RECT_OES:
6133 if (context->getClientMajorVersion() > 1)
6134 {
6135 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
6136 return false;
6137 }
6138 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006139 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006140 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006141 return false;
6142 }
6143
6144 return true;
6145}
6146
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006147template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLfloat *);
6148template bool ValidateTexParameterBase(Context *, TextureType, GLenum, GLsizei, const GLint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006149
Jamie Madill5b772312018-03-08 20:28:32 -05006150bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006151{
6152 if (index >= MAX_VERTEX_ATTRIBS)
6153 {
6154 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
6155 return false;
6156 }
6157
6158 return true;
6159}
6160
6161bool ValidateGetActiveUniformBlockivBase(Context *context,
6162 GLuint program,
6163 GLuint uniformBlockIndex,
6164 GLenum pname,
6165 GLsizei *length)
6166{
6167 if (length)
6168 {
6169 *length = 0;
6170 }
6171
6172 if (context->getClientMajorVersion() < 3)
6173 {
6174 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6175 return false;
6176 }
6177
6178 Program *programObject = GetValidProgram(context, program);
6179 if (!programObject)
6180 {
6181 return false;
6182 }
6183
6184 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6185 {
6186 context->handleError(InvalidValue()
6187 << "uniformBlockIndex exceeds active uniform block count.");
6188 return false;
6189 }
6190
6191 switch (pname)
6192 {
6193 case GL_UNIFORM_BLOCK_BINDING:
6194 case GL_UNIFORM_BLOCK_DATA_SIZE:
6195 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6196 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6197 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6198 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6199 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6200 break;
6201
6202 default:
6203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6204 return false;
6205 }
6206
6207 if (length)
6208 {
6209 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6210 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006211 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006212 programObject->getUniformBlockByIndex(uniformBlockIndex);
6213 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6214 }
6215 else
6216 {
6217 *length = 1;
6218 }
6219 }
6220
6221 return true;
6222}
6223
Jamie Madill9696d072017-08-26 23:19:57 -04006224template <typename ParamType>
6225bool ValidateSamplerParameterBase(Context *context,
6226 GLuint sampler,
6227 GLenum pname,
6228 GLsizei bufSize,
6229 ParamType *params)
6230{
6231 if (context->getClientMajorVersion() < 3)
6232 {
6233 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6234 return false;
6235 }
6236
6237 if (!context->isSampler(sampler))
6238 {
6239 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler);
6240 return false;
6241 }
6242
6243 const GLsizei minBufSize = 1;
6244 if (bufSize >= 0 && bufSize < minBufSize)
6245 {
6246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
6247 return false;
6248 }
6249
6250 switch (pname)
6251 {
6252 case GL_TEXTURE_WRAP_S:
6253 case GL_TEXTURE_WRAP_T:
6254 case GL_TEXTURE_WRAP_R:
6255 if (!ValidateTextureWrapModeValue(context, params, false))
6256 {
6257 return false;
6258 }
6259 break;
6260
6261 case GL_TEXTURE_MIN_FILTER:
6262 if (!ValidateTextureMinFilterValue(context, params, false))
6263 {
6264 return false;
6265 }
6266 break;
6267
6268 case GL_TEXTURE_MAG_FILTER:
6269 if (!ValidateTextureMagFilterValue(context, params))
6270 {
6271 return false;
6272 }
6273 break;
6274
6275 case GL_TEXTURE_MIN_LOD:
6276 case GL_TEXTURE_MAX_LOD:
6277 // any value is permissible
6278 break;
6279
6280 case GL_TEXTURE_COMPARE_MODE:
6281 if (!ValidateTextureCompareModeValue(context, params))
6282 {
6283 return false;
6284 }
6285 break;
6286
6287 case GL_TEXTURE_COMPARE_FUNC:
6288 if (!ValidateTextureCompareFuncValue(context, params))
6289 {
6290 return false;
6291 }
6292 break;
6293
6294 case GL_TEXTURE_SRGB_DECODE_EXT:
6295 if (!ValidateTextureSRGBDecodeValue(context, params))
6296 {
6297 return false;
6298 }
6299 break;
6300
Luc Ferron1b1a8642018-01-23 15:12:01 -05006301 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6302 {
6303 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6304 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6305 {
6306 return false;
6307 }
6308 }
6309 break;
6310
Jamie Madill9696d072017-08-26 23:19:57 -04006311 default:
6312 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6313 return false;
6314 }
6315
6316 return true;
6317}
6318
6319template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLfloat *);
6320template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, GLint *);
6321
6322bool ValidateGetSamplerParameterBase(Context *context,
6323 GLuint sampler,
6324 GLenum pname,
6325 GLsizei *length)
6326{
6327 if (length)
6328 {
6329 *length = 0;
6330 }
6331
6332 if (context->getClientMajorVersion() < 3)
6333 {
6334 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6335 return false;
6336 }
6337
6338 if (!context->isSampler(sampler))
6339 {
6340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler);
6341 return false;
6342 }
6343
6344 switch (pname)
6345 {
6346 case GL_TEXTURE_WRAP_S:
6347 case GL_TEXTURE_WRAP_T:
6348 case GL_TEXTURE_WRAP_R:
6349 case GL_TEXTURE_MIN_FILTER:
6350 case GL_TEXTURE_MAG_FILTER:
6351 case GL_TEXTURE_MIN_LOD:
6352 case GL_TEXTURE_MAX_LOD:
6353 case GL_TEXTURE_COMPARE_MODE:
6354 case GL_TEXTURE_COMPARE_FUNC:
6355 break;
6356
Luc Ferron1b1a8642018-01-23 15:12:01 -05006357 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6358 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6359 {
6360 return false;
6361 }
6362 break;
6363
Jamie Madill9696d072017-08-26 23:19:57 -04006364 case GL_TEXTURE_SRGB_DECODE_EXT:
6365 if (!context->getExtensions().textureSRGBDecode)
6366 {
6367 context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled.");
6368 return false;
6369 }
6370 break;
6371
6372 default:
6373 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6374 return false;
6375 }
6376
6377 if (length)
6378 {
6379 *length = 1;
6380 }
6381 return true;
6382}
6383
6384bool ValidateGetInternalFormativBase(Context *context,
6385 GLenum target,
6386 GLenum internalformat,
6387 GLenum pname,
6388 GLsizei bufSize,
6389 GLsizei *numParams)
6390{
6391 if (numParams)
6392 {
6393 *numParams = 0;
6394 }
6395
6396 if (context->getClientMajorVersion() < 3)
6397 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08006398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006399 return false;
6400 }
6401
6402 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006403 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006404 {
6405 context->handleError(InvalidEnum() << "Internal format is not renderable.");
6406 return false;
6407 }
6408
6409 switch (target)
6410 {
6411 case GL_RENDERBUFFER:
6412 break;
6413
6414 case GL_TEXTURE_2D_MULTISAMPLE:
6415 if (context->getClientVersion() < ES_3_1)
6416 {
Olli Etuahod310a432018-08-24 15:40:23 +03006417 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureTargetRequiresES31);
Jamie Madill9696d072017-08-26 23:19:57 -04006418 return false;
6419 }
6420 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006421 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6422 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006423 {
6424 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
6425 return false;
6426 }
6427 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006428 default:
6429 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTarget);
6430 return false;
6431 }
6432
6433 if (bufSize < 0)
6434 {
6435 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
6436 return false;
6437 }
6438
6439 GLsizei maxWriteParams = 0;
6440 switch (pname)
6441 {
6442 case GL_NUM_SAMPLE_COUNTS:
6443 maxWriteParams = 1;
6444 break;
6445
6446 case GL_SAMPLES:
6447 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6448 break;
6449
6450 default:
6451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6452 return false;
6453 }
6454
6455 if (numParams)
6456 {
6457 // glGetInternalFormativ will not overflow bufSize
6458 *numParams = std::min(bufSize, maxWriteParams);
6459 }
6460
6461 return true;
6462}
6463
Jamie Madille98b1b52018-03-08 09:47:23 -05006464bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6465{
Jamie Madill427064d2018-04-13 16:20:34 -04006466 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006467 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03006468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006469 return false;
6470 }
6471 return true;
6472}
6473
Lingfeng Yang038dd532018-03-29 17:31:52 -07006474bool ValidateMultitextureUnit(Context *context, GLenum texture)
6475{
6476 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6477 {
6478 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMultitextureUnit);
6479 return false;
6480 }
6481 return true;
6482}
6483
Olli Etuahod310a432018-08-24 15:40:23 +03006484bool ValidateTexStorageMultisample(Context *context,
6485 TextureType target,
6486 GLsizei samples,
6487 GLint internalFormat,
6488 GLsizei width,
6489 GLsizei height)
6490{
6491 const Caps &caps = context->getCaps();
6492 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6493 static_cast<GLuint>(height) > caps.max2DTextureSize)
6494 {
6495 ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureWidthOrHeightOutOfRange);
6496 return false;
6497 }
6498
6499 if (samples == 0)
6500 {
6501 ANGLE_VALIDATION_ERR(context, InvalidValue(), SamplesZero);
6502 return false;
6503 }
6504
6505 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6506 if (!formatCaps.textureAttachment)
6507 {
6508 ANGLE_VALIDATION_ERR(context, InvalidEnum(), RenderableInternalFormat);
6509 return false;
6510 }
6511
6512 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6513 // is one of the unsized base internalformats listed in table 8.11.
6514 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6515 if (formatInfo.internalFormat == GL_NONE)
6516 {
6517 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnsizedInternalFormatUnsupported);
6518 return false;
6519 }
6520
6521 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6522 {
6523 ANGLE_VALIDATION_ERR(context, InvalidOperation(), SamplesOutOfRange);
6524 return false;
6525 }
6526
6527 Texture *texture = context->getTargetTexture(target);
6528 if (!texture || texture->id() == 0)
6529 {
6530 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ZeroBoundToTarget);
6531 return false;
6532 }
6533
6534 if (texture->getImmutableFormat())
6535 {
6536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ImmutableTextureBound);
6537 return false;
6538 }
6539 return true;
6540}
6541
Jamie Madillc29968b2016-01-20 11:17:23 -05006542} // namespace gl