blob: b5dc8d8592f8b7e417b1745bacc426e21e9f77ee [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 Madill778bf092018-11-14 09:54:36 -050026#include "libANGLE/validationES2_autogen.h"
27#include "libANGLE/validationES3_autogen.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 Madille0472f32018-11-27 16:32:45 -050036using namespace err;
37
Jamie Madill1ca74672015-07-21 15:14:11 -040038namespace
39{
Luc Ferron9dbaeba2018-02-01 07:26:59 -050040bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
41{
42 // List of compressed format that require that the texture size is smaller than or a multiple of
43 // the compressed block size.
44 switch (internalFormat)
45 {
46 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
47 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
48 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
49 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
50 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
51 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
52 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
53 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
54 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
55 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
56 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
57 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
58 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
59 case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
60 case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +030061 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
62 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
63 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
64 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Luc Ferron9dbaeba2018-02-01 07:26:59 -050065 return true;
jchen10a99ed552017-09-22 08:10:32 +080066
Luc Ferron9dbaeba2018-02-01 07:26:59 -050067 default:
68 return false;
69 }
70}
71bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
72{
73 // Compressed sub textures have additional formats that requires exact size.
74 // ES 3.1, Section 8.7, Page 171
75 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
76 IsETC2EACFormat(internalFormat);
77}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030078
79bool DifferenceCanOverflow(GLint a, GLint b)
80{
81 CheckedNumeric<GLint> checkedA(a);
82 checkedA -= b;
83 // Use negation to make sure that the difference can't overflow regardless of the order.
84 checkedA = -checkedA;
85 return !checkedA.IsValid();
86}
87
Jamie Madill16e28fd2018-09-12 11:03:05 -040088bool ValidateDrawAttribsImpl(Context *context, GLint primcount, GLint maxVertex)
Jamie Madill1ca74672015-07-21 15:14:11 -040089{
Jamie Madill51af38b2018-04-15 08:50:56 -040090 // If we're drawing zero vertices, we have enough data.
Jamie Madill2da53562018-08-01 11:34:47 -040091 ASSERT(primcount > 0);
Jamie Madill51af38b2018-04-15 08:50:56 -040092
Jamie Madill88602e62018-08-08 12:49:30 -040093 // An overflow can happen when adding the offset. Check against a special constant.
94 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
95 VertexAttribute::kIntegerOverflow ||
96 context->getStateCache().getInstancedVertexElementLimit() ==
97 VertexAttribute::kIntegerOverflow)
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040098 {
Jamie Madille0472f32018-11-27 16:32:45 -050099 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madilla2d1d2d2018-08-01 11:34:46 -0400100 return false;
101 }
102
103 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
104 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
Jamie Madille0472f32018-11-27 16:32:45 -0500105 context->validationError(GL_INVALID_OPERATION, kInsufficientVertexBufferSize);
Jamie Madilla2d1d2d2018-08-01 11:34:46 -0400106 return false;
Jamie Madill1ca74672015-07-21 15:14:11 -0400107}
108
Jamie Madill16e28fd2018-09-12 11:03:05 -0400109ANGLE_INLINE bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex)
110{
111 if (maxVertex <= context->getStateCache().getNonInstancedVertexElementLimit() &&
112 (primcount - 1) <= context->getStateCache().getInstancedVertexElementLimit())
113 {
114 return true;
115 }
116 else
117 {
118 return ValidateDrawAttribsImpl(context, primcount, maxVertex);
119 }
120}
121
Jamie Madill5b772312018-03-08 20:28:32 -0500122bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -0400123{
124 switch (type)
125 {
126 // Types referenced in Table 3.4 of the ES 2.0.25 spec
127 case GL_UNSIGNED_BYTE:
128 case GL_UNSIGNED_SHORT_4_4_4_4:
129 case GL_UNSIGNED_SHORT_5_5_5_1:
130 case GL_UNSIGNED_SHORT_5_6_5:
131 return context->getClientVersion() >= ES_2_0;
132
133 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
134 case GL_BYTE:
135 case GL_INT:
136 case GL_SHORT:
137 case GL_UNSIGNED_INT:
138 case GL_UNSIGNED_INT_10F_11F_11F_REV:
139 case GL_UNSIGNED_INT_24_8:
140 case GL_UNSIGNED_INT_2_10_10_10_REV:
141 case GL_UNSIGNED_INT_5_9_9_9_REV:
142 case GL_UNSIGNED_SHORT:
143 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
144 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
145 return context->getClientVersion() >= ES_3_0;
146
147 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400148 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
149 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400150
151 case GL_HALF_FLOAT:
152 return context->getClientVersion() >= ES_3_0 ||
153 context->getExtensions().textureHalfFloat;
154
155 case GL_HALF_FLOAT_OES:
156 return context->getExtensions().colorBufferHalfFloat;
157
158 default:
159 return false;
160 }
161}
162
Jamie Madill5b772312018-03-08 20:28:32 -0500163bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400164{
165 switch (format)
166 {
167 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
168 case GL_RGBA:
169 case GL_RGB:
170 case GL_ALPHA:
171 return context->getClientVersion() >= ES_2_0;
172
173 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
174 case GL_RG:
175 case GL_RED:
176 case GL_RGBA_INTEGER:
177 case GL_RGB_INTEGER:
178 case GL_RG_INTEGER:
179 case GL_RED_INTEGER:
180 return context->getClientVersion() >= ES_3_0;
181
182 case GL_SRGB_ALPHA_EXT:
183 case GL_SRGB_EXT:
184 return context->getExtensions().sRGB;
185
186 case GL_BGRA_EXT:
187 return context->getExtensions().readFormatBGRA;
188
189 default:
190 return false;
191 }
192}
193
Jamie Madill5b772312018-03-08 20:28:32 -0500194bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400195 GLenum framebufferComponentType,
196 GLenum format,
197 GLenum type)
198{
199 switch (framebufferComponentType)
200 {
201 case GL_UNSIGNED_NORMALIZED:
202 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
203 // ReadPixels with BGRA even if the extension is not present
204 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
205 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
206 type == GL_UNSIGNED_BYTE);
207
208 case GL_SIGNED_NORMALIZED:
209 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
210
211 case GL_INT:
212 return (format == GL_RGBA_INTEGER && type == GL_INT);
213
214 case GL_UNSIGNED_INT:
215 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
216
217 case GL_FLOAT:
218 return (format == GL_RGBA && type == GL_FLOAT);
219
220 default:
221 UNREACHABLE();
222 return false;
223 }
224}
225
Geoff Langc1984ed2016-10-07 12:41:00 -0400226template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400227bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400228{
229 switch (ConvertToGLenum(params[0]))
230 {
231 case GL_CLAMP_TO_EDGE:
232 break;
233
Till Rathmannb8543632018-10-02 19:46:14 +0200234 case GL_CLAMP_TO_BORDER:
235 if (!context->getExtensions().textureBorderClamp)
236 {
Jamie Madille0472f32018-11-27 16:32:45 -0500237 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +0200238 return false;
239 }
240 break;
241
Geoff Langc1984ed2016-10-07 12:41:00 -0400242 case GL_REPEAT:
243 case GL_MIRRORED_REPEAT:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400244 if (restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400245 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400246 // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
Jamie Madille0472f32018-11-27 16:32:45 -0500247 context->validationError(GL_INVALID_ENUM, kInvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400248 return false;
249 }
250 break;
251
252 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500253 context->validationError(GL_INVALID_ENUM, kInvalidTextureWrap);
Geoff Langc1984ed2016-10-07 12:41:00 -0400254 return false;
255 }
256
257 return true;
258}
259
260template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400261bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400262{
263 switch (ConvertToGLenum(params[0]))
264 {
265 case GL_NEAREST:
266 case GL_LINEAR:
267 break;
268
269 case GL_NEAREST_MIPMAP_NEAREST:
270 case GL_LINEAR_MIPMAP_NEAREST:
271 case GL_NEAREST_MIPMAP_LINEAR:
272 case GL_LINEAR_MIPMAP_LINEAR:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400273 if (restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400274 {
275 // OES_EGL_image_external specifies this error.
Jamie Madille0472f32018-11-27 16:32:45 -0500276 context->validationError(GL_INVALID_ENUM, kInvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400277 return false;
278 }
279 break;
280
281 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500282 context->validationError(GL_INVALID_ENUM, kInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400283 return false;
284 }
285
286 return true;
287}
288
289template <typename ParamType>
290bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
291{
292 switch (ConvertToGLenum(params[0]))
293 {
294 case GL_NEAREST:
295 case GL_LINEAR:
296 break;
297
298 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_ENUM, kInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400300 return false;
301 }
302
303 return true;
304}
305
306template <typename ParamType>
307bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
308{
309 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
310 switch (ConvertToGLenum(params[0]))
311 {
312 case GL_NONE:
313 case GL_COMPARE_REF_TO_TEXTURE:
314 break;
315
316 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500317 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400318 return false;
319 }
320
321 return true;
322}
323
324template <typename ParamType>
325bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
326{
327 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
328 switch (ConvertToGLenum(params[0]))
329 {
330 case GL_LEQUAL:
331 case GL_GEQUAL:
332 case GL_LESS:
333 case GL_GREATER:
334 case GL_EQUAL:
335 case GL_NOTEQUAL:
336 case GL_ALWAYS:
337 case GL_NEVER:
338 break;
339
340 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500341 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400342 return false;
343 }
344
345 return true;
346}
347
348template <typename ParamType>
Geoff Lang81c6b572016-10-19 14:07:52 -0700349bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
350{
351 if (!context->getExtensions().textureSRGBDecode)
352 {
Jamie Madille0472f32018-11-27 16:32:45 -0500353 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang81c6b572016-10-19 14:07:52 -0700354 return false;
355 }
356
357 switch (ConvertToGLenum(params[0]))
358 {
359 case GL_DECODE_EXT:
360 case GL_SKIP_DECODE_EXT:
361 break;
362
363 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500364 context->validationError(GL_INVALID_ENUM, kUnknownParameter);
Geoff Lang81c6b572016-10-19 14:07:52 -0700365 return false;
366 }
367
368 return true;
369}
370
Luc Ferron1b1a8642018-01-23 15:12:01 -0500371bool ValidateTextureMaxAnisotropyExtensionEnabled(Context *context)
372{
373 if (!context->getExtensions().textureFilterAnisotropic)
374 {
Jamie Madille0472f32018-11-27 16:32:45 -0500375 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500376 return false;
377 }
378
379 return true;
380}
381
382bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
383{
384 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
385 {
386 return false;
387 }
388
389 GLfloat largest = context->getExtensions().maxTextureAnisotropy;
390
391 if (paramValue < 1 || paramValue > largest)
392 {
Jamie Madille0472f32018-11-27 16:32:45 -0500393 context->validationError(GL_INVALID_VALUE, kOutsideOfBounds);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500394 return false;
395 }
396
397 return true;
398}
399
Jamie Madill5b772312018-03-08 20:28:32 -0500400bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
Geoff Lange0cff192017-05-30 13:04:56 -0400401{
Jamie Madill785e8a02018-10-04 17:42:00 -0400402 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lange0cff192017-05-30 13:04:56 -0400403 const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
404
Jamie Madille7d80f32018-08-08 15:49:23 -0400405 return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
406 framebuffer->getDrawBufferTypeMask().to_ulong(),
407 program->getActiveOutputVariables().to_ulong(),
408 framebuffer->getDrawBufferMask().to_ulong());
Geoff Lange0cff192017-05-30 13:04:56 -0400409}
410
Jamie Madill5b772312018-03-08 20:28:32 -0500411bool ValidateVertexShaderAttributeTypeMatch(Context *context)
Geoff Lang9ab5b822017-05-30 16:19:23 -0400412{
Lingfeng Yang038dd532018-03-29 17:31:52 -0700413 const auto &glState = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -0400414 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400415 const VertexArray *vao = context->getGLState().getVertexArray();
416
Brandon Jonesc405ae72017-12-06 14:15:03 -0800417 unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
418 unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
419 unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
420
421 vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
422 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
423 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
424
Jamie Madille7d80f32018-08-08 15:49:23 -0400425 return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
426 vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
427 0xFFFF);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400428}
429
Jamie Madill493f9572018-05-24 19:52:15 -0400430bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
431 PrimitiveMode geometryShaderInputPrimitiveType)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800432{
433 // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
Jamie Madill493f9572018-05-24 19:52:15 -0400434 switch (drawMode)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800435 {
Jamie Madill493f9572018-05-24 19:52:15 -0400436 case PrimitiveMode::Points:
437 return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
438 case PrimitiveMode::Lines:
439 case PrimitiveMode::LineStrip:
440 case PrimitiveMode::LineLoop:
441 return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
442 case PrimitiveMode::LinesAdjacency:
443 case PrimitiveMode::LineStripAdjacency:
444 return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
445 case PrimitiveMode::Triangles:
446 case PrimitiveMode::TriangleFan:
447 case PrimitiveMode::TriangleStrip:
448 return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
449 case PrimitiveMode::TrianglesAdjacency:
450 case PrimitiveMode::TriangleStripAdjacency:
451 return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
Jiawei Shaofccebff2018-03-08 13:51:02 +0800452 default:
453 UNREACHABLE();
454 return false;
455 }
456}
457
Lingfeng Yangf97641c2018-06-21 19:22:45 -0700458// GLES1 texture parameters are a small subset of the others
459bool IsValidGLES1TextureParameter(GLenum pname)
460{
461 switch (pname)
462 {
463 case GL_TEXTURE_MAG_FILTER:
464 case GL_TEXTURE_MIN_FILTER:
465 case GL_TEXTURE_WRAP_S:
466 case GL_TEXTURE_WRAP_T:
467 case GL_TEXTURE_WRAP_R:
468 case GL_GENERATE_MIPMAP:
469 case GL_TEXTURE_CROP_RECT_OES:
470 return true;
471 default:
472 return false;
473 }
474}
Till Rathmannb8543632018-10-02 19:46:14 +0200475
476unsigned int GetSamplerParameterCount(GLenum pname)
477{
478 return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
479}
480
Geoff Langf41a7152016-09-19 15:11:17 -0400481} // anonymous namespace
482
Brandon Jonesd1049182018-03-28 10:02:20 -0700483void SetRobustLengthParam(GLsizei *length, GLsizei value)
484{
485 if (length)
486 {
487 *length = value;
488 }
489}
490
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500491bool IsETC2EACFormat(const GLenum format)
492{
493 // ES 3.1, Table 8.19
494 switch (format)
495 {
496 case GL_COMPRESSED_R11_EAC:
497 case GL_COMPRESSED_SIGNED_R11_EAC:
498 case GL_COMPRESSED_RG11_EAC:
499 case GL_COMPRESSED_SIGNED_RG11_EAC:
500 case GL_COMPRESSED_RGB8_ETC2:
501 case GL_COMPRESSED_SRGB8_ETC2:
502 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
503 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
504 case GL_COMPRESSED_RGBA8_ETC2_EAC:
505 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
506 return true;
507
508 default:
509 return false;
510 }
511}
512
Jamie Madill5b772312018-03-08 20:28:32 -0500513bool ValidTextureTarget(const Context *context, TextureType type)
Jamie Madill35d15012013-10-07 10:46:37 -0400514{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800515 switch (type)
Jamie Madill35d15012013-10-07 10:46:37 -0400516 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800517 case TextureType::_2D:
518 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800519 return true;
Jamie Madill35d15012013-10-07 10:46:37 -0400520
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800521 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400522 return context->getExtensions().textureRectangle;
523
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800524 case TextureType::_3D:
525 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800526 return (context->getClientMajorVersion() >= 3);
Jamie Madilld7460c72014-01-21 16:38:14 -0500527
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800528 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800529 return (context->getClientVersion() >= Version(3, 1) ||
530 context->getExtensions().textureMultisample);
Olli Etuahod310a432018-08-24 15:40:23 +0300531 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300532 return context->getExtensions().textureStorageMultisample2DArray;
Geoff Lang3b573612016-10-31 14:08:10 -0400533
He Yunchaoced53ae2016-11-29 15:00:51 +0800534 default:
535 return false;
Jamie Madilld7460c72014-01-21 16:38:14 -0500536 }
Jamie Madill35d15012013-10-07 10:46:37 -0400537}
538
Jamie Madill5b772312018-03-08 20:28:32 -0500539bool ValidTexture2DTarget(const Context *context, TextureType type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500540{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800541 switch (type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500542 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800543 case TextureType::_2D:
544 case TextureType::CubeMap:
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500545 return true;
546
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800547 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400548 return context->getExtensions().textureRectangle;
549
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500550 default:
551 return false;
552 }
553}
554
Jamie Madill5b772312018-03-08 20:28:32 -0500555bool ValidTexture3DTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500556{
557 switch (target)
558 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800559 case TextureType::_3D:
560 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +0300561 return (context->getClientMajorVersion() >= 3);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500562
563 default:
564 return false;
565 }
566}
567
Ian Ewellbda75592016-04-18 17:25:54 -0400568// Most texture GL calls are not compatible with external textures, so we have a separate validation
569// function for use in the GL calls that do
Jamie Madill5b772312018-03-08 20:28:32 -0500570bool ValidTextureExternalTarget(const Context *context, TextureType target)
Ian Ewellbda75592016-04-18 17:25:54 -0400571{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800572 return (target == TextureType::External) &&
Ian Ewellbda75592016-04-18 17:25:54 -0400573 (context->getExtensions().eglImageExternal ||
574 context->getExtensions().eglStreamConsumerExternal);
575}
576
Shannon Woods4dfed832014-03-17 20:03:39 -0400577// This function differs from ValidTextureTarget in that the target must be
578// usable as the destination of a 2D operation-- so a cube face is valid, but
579// GL_TEXTURE_CUBE_MAP is not.
Jamie Madill560a8d82014-05-21 13:06:20 -0400580// Note: duplicate of IsInternalTextureTarget
Jamie Madill5b772312018-03-08 20:28:32 -0500581bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
Shannon Woods4dfed832014-03-17 20:03:39 -0400582{
583 switch (target)
584 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800585 case TextureTarget::_2D:
586 case TextureTarget::CubeMapNegativeX:
587 case TextureTarget::CubeMapNegativeY:
588 case TextureTarget::CubeMapNegativeZ:
589 case TextureTarget::CubeMapPositiveX:
590 case TextureTarget::CubeMapPositiveY:
591 case TextureTarget::CubeMapPositiveZ:
He Yunchaoced53ae2016-11-29 15:00:51 +0800592 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800593 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400594 return context->getExtensions().textureRectangle;
He Yunchaoced53ae2016-11-29 15:00:51 +0800595 default:
596 return false;
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500597 }
598}
599
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800600bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400601 PrimitiveMode transformFeedbackPrimitiveMode,
602 PrimitiveMode renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800603{
604 ASSERT(context);
605
606 if (!context->getExtensions().geometryShader)
607 {
608 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
609 // that does not match the current transform feedback object's draw mode (if transform
610 // feedback is active), (3.0.2, section 2.14, pg 86)
611 return transformFeedbackPrimitiveMode == renderPrimitiveMode;
612 }
613
614 // [GL_EXT_geometry_shader] Table 12.1gs
Jamie Madill493f9572018-05-24 19:52:15 -0400615 switch (renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800616 {
Jamie Madill493f9572018-05-24 19:52:15 -0400617 case PrimitiveMode::Points:
618 return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
619 case PrimitiveMode::Lines:
620 case PrimitiveMode::LineStrip:
621 case PrimitiveMode::LineLoop:
622 return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
623 case PrimitiveMode::Triangles:
624 case PrimitiveMode::TriangleFan:
625 case PrimitiveMode::TriangleStrip:
626 return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800627 default:
628 UNREACHABLE();
629 return false;
630 }
631}
632
Jamie Madill5b772312018-03-08 20:28:32 -0500633bool ValidateDrawElementsInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400634 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400635 GLsizei count,
636 GLenum type,
637 const GLvoid *indices,
638 GLsizei primcount)
639{
640 if (primcount < 0)
641 {
Jamie Madille0472f32018-11-27 16:32:45 -0500642 context->validationError(GL_INVALID_VALUE, kNegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400643 return false;
644 }
645
646 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount))
647 {
648 return false;
649 }
650
Jamie Madill9fdaa492018-02-16 10:52:11 -0500651 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400652}
653
654bool ValidateDrawArraysInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400655 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400656 GLint first,
657 GLsizei count,
658 GLsizei primcount)
659{
660 if (primcount < 0)
661 {
Jamie Madille0472f32018-11-27 16:32:45 -0500662 context->validationError(GL_INVALID_VALUE, kNegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400663 return false;
664 }
665
666 if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
667 {
668 return false;
669 }
670
Jamie Madill9fdaa492018-02-16 10:52:11 -0500671 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400672}
673
Jamie Madill5b772312018-03-08 20:28:32 -0500674bool ValidateDrawInstancedANGLE(Context *context)
Jamie Madillbe849e42017-05-02 15:49:00 -0400675{
676 // Verify there is at least one active attribute with a divisor of zero
677 const State &state = context->getGLState();
678
Jamie Madill785e8a02018-10-04 17:42:00 -0400679 Program *program = state.getLinkedProgram(context);
Jamie Madillbe849e42017-05-02 15:49:00 -0400680
681 const auto &attribs = state.getVertexArray()->getVertexAttributes();
682 const auto &bindings = state.getVertexArray()->getVertexBindings();
683 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
684 {
685 const VertexAttribute &attrib = attribs[attributeIndex];
686 const VertexBinding &binding = bindings[attrib.bindingIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +0300687 if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400688 {
689 return true;
690 }
691 }
692
Jamie Madille0472f32018-11-27 16:32:45 -0500693 context->validationError(GL_INVALID_OPERATION, kNoZeroDivisor);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695}
696
Jamie Madill5b772312018-03-08 20:28:32 -0500697bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500698{
699 switch (target)
700 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800701 case TextureType::_3D:
702 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800703 return true;
704 default:
705 return false;
Shannon Woods4dfed832014-03-17 20:03:39 -0400706 }
707}
708
Jamie Madill5b772312018-03-08 20:28:32 -0500709bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
He Yunchao11b038b2016-11-22 21:24:04 +0800710{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800711 switch (type)
He Yunchao11b038b2016-11-22 21:24:04 +0800712 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800713 case TextureType::_2D:
714 case TextureType::_2DArray:
715 case TextureType::_2DMultisample:
716 case TextureType::CubeMap:
717 case TextureType::_3D:
He Yunchao11b038b2016-11-22 21:24:04 +0800718 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800719 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400720 return context->getExtensions().textureRectangle;
Olli Etuahod310a432018-08-24 15:40:23 +0300721 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300722 return context->getExtensions().textureStorageMultisample2DArray;
He Yunchao11b038b2016-11-22 21:24:04 +0800723 default:
724 return false;
725 }
726}
727
Jamie Madill5b772312018-03-08 20:28:32 -0500728bool ValidFramebufferTarget(const Context *context, GLenum target)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500729{
He Yunchaoced53ae2016-11-29 15:00:51 +0800730 static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
731 GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
Geoff Langd4475812015-03-18 10:53:05 -0400732 "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500733
734 switch (target)
735 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800736 case GL_FRAMEBUFFER:
737 return true;
Geoff Lange8afa902017-09-27 15:00:43 -0400738
He Yunchaoced53ae2016-11-29 15:00:51 +0800739 case GL_READ_FRAMEBUFFER:
He Yunchaoced53ae2016-11-29 15:00:51 +0800740 case GL_DRAW_FRAMEBUFFER:
Geoff Lange8afa902017-09-27 15:00:43 -0400741 return (context->getExtensions().framebufferBlit ||
742 context->getClientMajorVersion() >= 3);
743
He Yunchaoced53ae2016-11-29 15:00:51 +0800744 default:
745 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500746 }
747}
748
Jamie Madill5b772312018-03-08 20:28:32 -0500749bool ValidMipLevel(const Context *context, TextureType type, GLint level)
Geoff Langce635692013-09-24 13:56:32 -0400750{
Jamie Madillc29968b2016-01-20 11:17:23 -0500751 const auto &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -0400752 size_t maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800753 switch (type)
Geoff Langce635692013-09-24 13:56:32 -0400754 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800755 case TextureType::_2D:
756 case TextureType::_2DArray:
757 case TextureType::_2DMultisample:
Olli Etuahod310a432018-08-24 15:40:23 +0300758 case TextureType::_2DMultisampleArray:
759 // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
760 // level-of-detail" for multisample textures should be. Could maybe make it zero.
Jamie Madillc29968b2016-01-20 11:17:23 -0500761 maxDimension = caps.max2DTextureSize;
762 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800763 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800764 maxDimension = caps.maxCubeMapTextureSize;
765 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800766 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400767 return level == 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800768 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800769 maxDimension = caps.max3DTextureSize;
770 break;
He Yunchaoced53ae2016-11-29 15:00:51 +0800771 default:
772 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400773 }
774
Jamie Madill43da7c42018-08-01 11:34:49 -0400775 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400776}
777
Jamie Madill5b772312018-03-08 20:28:32 -0500778bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800779 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700780 GLint level,
781 GLsizei width,
782 GLsizei height,
783 GLsizei depth,
784 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400785{
Brandon Jones6cad5662017-06-14 13:25:13 -0700786 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400787 {
Jamie Madille0472f32018-11-27 16:32:45 -0500788 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400789 return false;
790 }
Austin Kinross08528e12015-10-07 16:24:40 -0700791 // TexSubImage parameters can be NPOT without textureNPOT extension,
792 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500793 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500794 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500795 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400796 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400797 {
Jamie Madille0472f32018-11-27 16:32:45 -0500798 context->validationError(GL_INVALID_VALUE, kTextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400799 return false;
800 }
801
802 if (!ValidMipLevel(context, target, level))
803 {
Jamie Madille0472f32018-11-27 16:32:45 -0500804 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400805 return false;
806 }
807
808 return true;
809}
810
Geoff Lang966c9402017-04-18 12:38:27 -0400811bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
812{
813 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
814 (size % blockSize == 0);
815}
816
Jamie Madill5b772312018-03-08 20:28:32 -0500817bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500818 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400819 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500820 GLsizei width,
821 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400822{
Jamie Madill43da7c42018-08-01 11:34:49 -0400823 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400824 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400825 {
826 return false;
827 }
828
Geoff Lang966c9402017-04-18 12:38:27 -0400829 if (width < 0 || height < 0)
830 {
831 return false;
832 }
833
834 if (CompressedTextureFormatRequiresExactSize(internalFormat))
835 {
836 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
837 // block size for level 0 but WebGL disallows this.
838 bool smallerThanBlockSizeAllowed =
839 level > 0 || !context->getExtensions().webglCompatibility;
840
841 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
842 smallerThanBlockSizeAllowed) ||
843 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
844 smallerThanBlockSizeAllowed))
845 {
846 return false;
847 }
848 }
849
850 return true;
851}
852
Jamie Madill5b772312018-03-08 20:28:32 -0500853bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400854 GLenum internalFormat,
855 GLint xoffset,
856 GLint yoffset,
857 GLsizei width,
858 GLsizei height,
859 size_t textureWidth,
860 size_t textureHeight)
861{
Jamie Madill43da7c42018-08-01 11:34:49 -0400862 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400863 if (!formatInfo.compressed)
864 {
865 return false;
866 }
867
Geoff Lang44ff5a72017-02-03 15:15:43 -0500868 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400869 {
870 return false;
871 }
872
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500873 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400874 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500875 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400876 yoffset % formatInfo.compressedBlockHeight != 0)
877 {
878 return false;
879 }
880
881 // Allowed to either have data that is a multiple of block size or is smaller than the block
882 // size but fills the entire mip
883 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
884 static_cast<size_t>(width) == textureWidth &&
885 static_cast<size_t>(height) == textureHeight;
886 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
887 (height % formatInfo.compressedBlockHeight) == 0;
888 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400889 {
890 return false;
891 }
892 }
893
Geoff Langd4f180b2013-09-24 13:57:44 -0400894 return true;
895}
896
Jamie Madill5b772312018-03-08 20:28:32 -0500897bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800898 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400899 GLsizei width,
900 GLsizei height,
901 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400902 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400903 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400904 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400905 GLsizei imageSize)
906{
Jamie Madill43da7c42018-08-01 11:34:49 -0400907 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400908 if (pixelUnpackBuffer == nullptr && imageSize < 0)
909 {
910 // Checks are not required
911 return true;
912 }
913
914 // ...the data would be unpacked from the buffer object such that the memory reads required
915 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400916 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400917 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400918 const Extents size(width, height, depth);
Geoff Langff5b2d52016-09-07 11:32:23 -0400919 const auto &unpack = context->getGLState().getUnpackState();
920
Jamie Madill7f232932018-09-12 11:03:06 -0400921 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
922 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400923 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400924 {
Jamie Madille0472f32018-11-27 16:32:45 -0500925 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400926 return false;
927 }
928
Geoff Langff5b2d52016-09-07 11:32:23 -0400929 if (pixelUnpackBuffer)
930 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400931 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400932 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
933 checkedEndByte += checkedOffset;
934
935 if (!checkedEndByte.IsValid() ||
936 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
937 {
938 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -0500939 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400940 return false;
941 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800942 if (context->getExtensions().webglCompatibility &&
943 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
944 {
Jamie Madill610640f2018-11-21 17:28:41 -0500945 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -0500946 kPixelUnpackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -0800947 return false;
948 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400949 }
950 else
951 {
952 ASSERT(imageSize >= 0);
953 if (pixels == nullptr && imageSize != 0)
954 {
Jamie Madill610640f2018-11-21 17:28:41 -0500955 context->validationError(GL_INVALID_OPERATION,
956 "imageSize must be 0 if no texture data is provided.");
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400957 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400958 }
959
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400960 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400961 {
Jamie Madill610640f2018-11-21 17:28:41 -0500962 context->validationError(GL_INVALID_OPERATION, "imageSize is too small");
Geoff Langff5b2d52016-09-07 11:32:23 -0400963 return false;
964 }
965 }
966
967 return true;
968}
969
Corentin Wallezad3ae902018-03-09 13:40:42 -0500970bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500971{
Geoff Lang37dde692014-01-31 16:34:54 -0500972 switch (queryType)
973 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500974 case QueryType::AnySamples:
975 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400976 return context->getClientMajorVersion() >= 3 ||
977 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500978 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800979 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500980 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800981 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500982 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800983 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500984 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800985 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800986 default:
987 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500988 }
989}
990
Jamie Madill5b772312018-03-08 20:28:32 -0500991bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400992 GLenum type,
993 GLboolean normalized,
994 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400995 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400996 bool pureInteger)
997{
998 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -0400999 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
1000 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
1001 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
1002 // parameter exceeds 255.
1003 constexpr GLsizei kMaxWebGLStride = 255;
1004 if (stride > kMaxWebGLStride)
1005 {
Jamie Madill610640f2018-11-21 17:28:41 -05001006 context->validationError(GL_INVALID_VALUE,
1007 "Stride is over the maximum stride allowed by WebGL.");
Geoff Lang2d62ab72017-03-23 16:54:40 -04001008 return false;
1009 }
1010
1011 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1012 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1013 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1014 // or an INVALID_OPERATION error is generated.
Frank Henigmand633b152018-10-04 23:34:31 -04001015 angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1016 size_t typeSize = GetVertexFormatSize(internalType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001017
1018 ASSERT(isPow2(typeSize) && typeSize > 0);
1019 size_t sizeMask = (typeSize - 1);
1020 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1021 {
Jamie Madille0472f32018-11-27 16:32:45 -05001022 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001023 return false;
1024 }
1025
1026 if ((stride & sizeMask) != 0)
1027 {
Jamie Madille0472f32018-11-27 16:32:45 -05001028 context->validationError(GL_INVALID_OPERATION, kStrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001029 return false;
1030 }
1031
1032 return true;
1033}
1034
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001035Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001036{
He Yunchaoced53ae2016-11-29 15:00:51 +08001037 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1038 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1039 // or program object and INVALID_OPERATION if the provided name identifies an object
1040 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001041
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001042 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001043
1044 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001045 {
Dian Xiang769769a2015-09-09 15:20:08 -07001046 if (context->getShader(id))
1047 {
Jamie Madille0472f32018-11-27 16:32:45 -05001048 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001049 }
1050 else
1051 {
Jamie Madille0472f32018-11-27 16:32:45 -05001052 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001053 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001054 }
Dian Xiang769769a2015-09-09 15:20:08 -07001055
1056 return validProgram;
1057}
1058
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001059Program *GetValidProgram(Context *context, GLuint id)
1060{
1061 Program *program = GetValidProgramNoResolve(context, id);
1062 if (program)
1063 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001064 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001065 }
1066 return program;
1067}
1068
Jamie Madill5b772312018-03-08 20:28:32 -05001069Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001070{
1071 // See ValidProgram for spec details.
1072
1073 Shader *validShader = context->getShader(id);
1074
1075 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001076 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001077 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001078 {
Jamie Madille0472f32018-11-27 16:32:45 -05001079 context->validationError(GL_INVALID_OPERATION, kExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001080 }
1081 else
1082 {
Jamie Madille0472f32018-11-27 16:32:45 -05001083 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001084 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001085 }
Dian Xiang769769a2015-09-09 15:20:08 -07001086
1087 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001088}
1089
Jamie Madill43da7c42018-08-01 11:34:49 -04001090bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001091{
Geoff Langfa125c92017-10-24 13:01:46 -04001092 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001093 {
Geoff Langfa125c92017-10-24 13:01:46 -04001094 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1095 {
Jamie Madille0472f32018-11-27 16:32:45 -05001096 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langfa125c92017-10-24 13:01:46 -04001097 return false;
1098 }
Jamie Madillb4472272014-07-03 10:38:55 -04001099
Geoff Langfa125c92017-10-24 13:01:46 -04001100 // Color attachment 0 is validated below because it is always valid
1101 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001102 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001103 {
Jamie Madille0472f32018-11-27 16:32:45 -05001104 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001105 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001106 }
1107 }
1108 else
1109 {
1110 switch (attachment)
1111 {
Geoff Langfa125c92017-10-24 13:01:46 -04001112 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001113 case GL_DEPTH_ATTACHMENT:
1114 case GL_STENCIL_ATTACHMENT:
1115 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001116
He Yunchaoced53ae2016-11-29 15:00:51 +08001117 case GL_DEPTH_STENCIL_ATTACHMENT:
1118 if (!context->getExtensions().webglCompatibility &&
1119 context->getClientMajorVersion() < 3)
1120 {
Jamie Madille0472f32018-11-27 16:32:45 -05001121 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001122 return false;
1123 }
1124 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001125
He Yunchaoced53ae2016-11-29 15:00:51 +08001126 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001127 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001128 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001129 }
1130 }
1131
1132 return true;
1133}
1134
Jamie Madill5b772312018-03-08 20:28:32 -05001135bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001136 GLenum target,
1137 GLsizei samples,
1138 GLenum internalformat,
1139 GLsizei width,
1140 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001141{
1142 switch (target)
1143 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001144 case GL_RENDERBUFFER:
1145 break;
1146 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001148 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001149 }
1150
1151 if (width < 0 || height < 0 || samples < 0)
1152 {
Jamie Madille0472f32018-11-27 16:32:45 -05001153 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001154 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001155 }
1156
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001157 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1158 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1159
1160 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001161 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001162 {
Jamie Madille0472f32018-11-27 16:32:45 -05001163 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001164 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 }
1166
1167 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1168 // 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 -08001169 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001170 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001171 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001172 {
Jamie Madille0472f32018-11-27 16:32:45 -05001173 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001174 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001175 }
1176
Geoff Langaae65a42014-05-26 12:43:44 -04001177 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001178 {
Jamie Madille0472f32018-11-27 16:32:45 -05001179 context->validationError(GL_INVALID_VALUE, kResourceMaxRenderbufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04001180 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 }
1182
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001183 GLuint handle = context->getGLState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001184 if (handle == 0)
1185 {
Jamie Madille0472f32018-11-27 16:32:45 -05001186 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001187 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001188 }
1189
1190 return true;
1191}
1192
Jamie Madill43da7c42018-08-01 11:34:49 -04001193bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 GLenum target,
1195 GLenum attachment,
1196 GLenum renderbuffertarget,
1197 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001198{
Geoff Lange8afa902017-09-27 15:00:43 -04001199 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001200 {
Jamie Madille0472f32018-11-27 16:32:45 -05001201 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001202 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001203 }
1204
Jamie Madill43da7c42018-08-01 11:34:49 -04001205 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001206
Jamie Madill84115c92015-04-23 15:00:07 -04001207 ASSERT(framebuffer);
1208 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001209 {
Jamie Madille0472f32018-11-27 16:32:45 -05001210 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001211 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001212 }
1213
Jamie Madillb4472272014-07-03 10:38:55 -04001214 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001215 {
Jamie Madillb4472272014-07-03 10:38:55 -04001216 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001217 }
1218
Jamie Madillab9d82c2014-01-21 16:38:14 -05001219 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1220 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1221 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1222 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1223 if (renderbuffer != 0)
1224 {
1225 if (!context->getRenderbuffer(renderbuffer))
1226 {
Jamie Madille0472f32018-11-27 16:32:45 -05001227 context->validationError(GL_INVALID_OPERATION, kInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001228 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001229 }
1230 }
1231
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001232 return true;
1233}
1234
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001235bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001236 GLint srcX0,
1237 GLint srcY0,
1238 GLint srcX1,
1239 GLint srcY1,
1240 GLint dstX0,
1241 GLint dstY0,
1242 GLint dstX1,
1243 GLint dstY1,
1244 GLbitfield mask,
1245 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001246{
1247 switch (filter)
1248 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001249 case GL_NEAREST:
1250 break;
1251 case GL_LINEAR:
1252 break;
1253 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001254 context->validationError(GL_INVALID_ENUM, kBlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001255 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001256 }
1257
1258 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1259 {
Jamie Madille0472f32018-11-27 16:32:45 -05001260 context->validationError(GL_INVALID_VALUE, kBlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001261 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 }
1263
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001264 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1265 // color buffer, leaving only nearest being unfiltered from above
1266 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1267 {
Jamie Madille0472f32018-11-27 16:32:45 -05001268 context->validationError(GL_INVALID_OPERATION, kBlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001269 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001270 }
1271
Jamie Madill7f232932018-09-12 11:03:06 -04001272 const auto &glState = context->getGLState();
1273 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1274 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001275
1276 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001277 {
Jamie Madille0472f32018-11-27 16:32:45 -05001278 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001279 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001280 }
1281
Jamie Madill427064d2018-04-13 16:20:34 -04001282 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001283 {
Jamie Madill48faf802014-11-06 15:27:22 -05001284 return false;
1285 }
1286
Jamie Madill427064d2018-04-13 16:20:34 -04001287 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001288 {
Jamie Madill48faf802014-11-06 15:27:22 -05001289 return false;
1290 }
1291
Qin Jiajiaaef92162018-02-27 13:51:44 +08001292 if (readFramebuffer->id() == drawFramebuffer->id())
1293 {
Jamie Madille0472f32018-11-27 16:32:45 -05001294 context->validationError(GL_INVALID_OPERATION, kBlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001295 return false;
1296 }
1297
Jamie Madille98b1b52018-03-08 09:47:23 -05001298 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001299 {
Geoff Langb1196682014-07-23 13:47:29 -04001300 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001301 }
1302
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001303 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1304 // always run it in order to avoid triggering driver bugs.
1305 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1306 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001307 {
Jamie Madille0472f32018-11-27 16:32:45 -05001308 context->validationError(GL_INVALID_VALUE, kBlitDimensionsOutOfRange);
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001309 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001310 }
1311
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001312 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1313
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001314 if (mask & GL_COLOR_BUFFER_BIT)
1315 {
Jamie Madill7f232932018-09-12 11:03:06 -04001316 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1317 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001318
He Yunchao66a41a22016-12-15 16:45:05 +08001319 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001320 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001321 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001322
Geoff Langa15472a2015-08-11 11:48:03 -04001323 for (size_t drawbufferIdx = 0;
1324 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001325 {
Geoff Langa15472a2015-08-11 11:48:03 -04001326 const FramebufferAttachment *attachment =
1327 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1328 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001330 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001331
Geoff Langb2f3d052013-08-13 12:49:27 -04001332 // The GL ES 3.0.2 spec (pg 193) states that:
1333 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1335 // as well
1336 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1337 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001338 // Changes with EXT_color_buffer_float:
1339 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001340 GLenum readComponentType = readFormat.info->componentType;
1341 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001342 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001343 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001344 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001345 drawComponentType == GL_SIGNED_NORMALIZED);
1346
1347 if (extensions.colorBufferFloat)
1348 {
1349 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1350 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1351
1352 if (readFixedOrFloat != drawFixedOrFloat)
1353 {
Jamie Madill610640f2018-11-21 17:28:41 -05001354 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001355 kBlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001356 return false;
1357 }
1358 }
1359 else if (readFixedPoint != drawFixedPoint)
1360 {
Jamie Madille0472f32018-11-27 16:32:45 -05001361 context->validationError(GL_INVALID_OPERATION, kBlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001362 return false;
1363 }
1364
1365 if (readComponentType == GL_UNSIGNED_INT &&
1366 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001367 {
Jamie Madill610640f2018-11-21 17:28:41 -05001368 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001369 kBlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001370 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001371 }
1372
Jamie Madill6163c752015-12-07 16:32:59 -05001373 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001374 {
Jamie Madill610640f2018-11-21 17:28:41 -05001375 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001376 kBlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001377 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001378 }
1379
Jamie Madilla3944d42016-07-22 22:13:26 -04001380 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001381 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001382 {
Jamie Madill610640f2018-11-21 17:28:41 -05001383 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001384 kBlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001385 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001386 }
Geoff Lange4915782017-04-12 15:19:07 -04001387
1388 if (context->getExtensions().webglCompatibility &&
1389 *readColorBuffer == *attachment)
1390 {
Jamie Madille0472f32018-11-27 16:32:45 -05001391 context->validationError(GL_INVALID_OPERATION, kBlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001392 return false;
1393 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001394 }
1395 }
1396
Jamie Madilla3944d42016-07-22 22:13:26 -04001397 if ((readFormat.info->componentType == GL_INT ||
1398 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1399 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001400 {
Jamie Madille0472f32018-11-27 16:32:45 -05001401 context->validationError(GL_INVALID_OPERATION, kBlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001402 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001403 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001404 }
He Yunchao66a41a22016-12-15 16:45:05 +08001405 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1406 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1407 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1408 // situation is an application error that would lead to a crash in ANGLE.
1409 else if (drawFramebuffer->hasEnabledDrawBuffer())
1410 {
Jamie Madille0472f32018-11-27 16:32:45 -05001411 context->validationError(GL_INVALID_OPERATION, kBlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001412 return false;
1413 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001414 }
1415
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001417 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1418 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001419 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001420 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001421 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001422 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001423 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001424 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001425 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001426
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001427 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001428 {
Kenneth Russell69382852017-07-21 16:38:44 -04001429 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001430 {
Jamie Madill610640f2018-11-21 17:28:41 -05001431 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05001432 kBlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001433 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001434 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001435
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001436 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001437 {
Jamie Madille0472f32018-11-27 16:32:45 -05001438 context->validationError(GL_INVALID_OPERATION, kBlitMultisampledBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001439 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001440 }
Geoff Lange4915782017-04-12 15:19:07 -04001441
1442 if (context->getExtensions().webglCompatibility && *readBuffer == *drawBuffer)
1443 {
Jamie Madille0472f32018-11-27 16:32:45 -05001444 context->validationError(GL_INVALID_OPERATION, kBlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001445 return false;
1446 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001447 }
He Yunchao66a41a22016-12-15 16:45:05 +08001448 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1449 else if (drawBuffer)
1450 {
Jamie Madille0472f32018-11-27 16:32:45 -05001451 context->validationError(GL_INVALID_OPERATION, kBlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001452 return false;
1453 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001454 }
1455 }
1456
Martin Radeva3ed4572017-07-27 18:29:37 +03001457 // ANGLE_multiview, Revision 1:
1458 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001459 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1460 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1461 // views in the current read framebuffer is more than one.
1462 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001463 {
Jamie Madille0472f32018-11-27 16:32:45 -05001464 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001465 return false;
1466 }
1467 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1468 {
Jamie Madille0472f32018-11-27 16:32:45 -05001469 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kBlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001470 return false;
1471 }
1472
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001473 return true;
1474}
1475
Jamie Madill4928b7c2017-06-20 12:57:39 -04001476bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001477 GLint x,
1478 GLint y,
1479 GLsizei width,
1480 GLsizei height,
1481 GLenum format,
1482 GLenum type,
1483 GLsizei bufSize,
1484 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001485 GLsizei *columns,
1486 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001487 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001488{
1489 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001490 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001491 return false;
1492 }
1493
Brandon Jonesd1049182018-03-28 10:02:20 -07001494 GLsizei writeLength = 0;
1495 GLsizei writeColumns = 0;
1496 GLsizei writeRows = 0;
1497
1498 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1499 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001500 {
Geoff Langb1196682014-07-23 13:47:29 -04001501 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001502 }
1503
Brandon Jonesd1049182018-03-28 10:02:20 -07001504 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001505 {
Geoff Langb1196682014-07-23 13:47:29 -04001506 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001507 }
1508
Brandon Jonesd1049182018-03-28 10:02:20 -07001509 SetRobustLengthParam(length, writeLength);
1510 SetRobustLengthParam(columns, writeColumns);
1511 SetRobustLengthParam(rows, writeRows);
1512
Jamie Madillc29968b2016-01-20 11:17:23 -05001513 return true;
1514}
1515
1516bool ValidateReadnPixelsEXT(Context *context,
1517 GLint x,
1518 GLint y,
1519 GLsizei width,
1520 GLsizei height,
1521 GLenum format,
1522 GLenum type,
1523 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001524 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001525{
1526 if (bufSize < 0)
1527 {
Jamie Madille0472f32018-11-27 16:32:45 -05001528 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001529 return false;
1530 }
1531
Geoff Lang62fce5b2016-09-30 10:46:35 -04001532 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001533 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001534}
Jamie Madill26e91952014-03-05 15:01:27 -05001535
Jamie Madill4928b7c2017-06-20 12:57:39 -04001536bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001537 GLint x,
1538 GLint y,
1539 GLsizei width,
1540 GLsizei height,
1541 GLenum format,
1542 GLenum type,
1543 GLsizei bufSize,
1544 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001545 GLsizei *columns,
1546 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001547 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001548{
Brandon Jonesd1049182018-03-28 10:02:20 -07001549 GLsizei writeLength = 0;
1550 GLsizei writeColumns = 0;
1551 GLsizei writeRows = 0;
1552
Geoff Lang62fce5b2016-09-30 10:46:35 -04001553 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001554 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001555 return false;
1556 }
1557
Brandon Jonesd1049182018-03-28 10:02:20 -07001558 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1559 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001560 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001561 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001562 }
1563
Brandon Jonesd1049182018-03-28 10:02:20 -07001564 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001565 {
1566 return false;
1567 }
1568
Brandon Jonesd1049182018-03-28 10:02:20 -07001569 SetRobustLengthParam(length, writeLength);
1570 SetRobustLengthParam(columns, writeColumns);
1571 SetRobustLengthParam(rows, writeRows);
1572
Geoff Lang62fce5b2016-09-30 10:46:35 -04001573 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001574}
1575
Jamie Madill43da7c42018-08-01 11:34:49 -04001576bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001577{
1578 if (!context->getExtensions().occlusionQueryBoolean &&
1579 !context->getExtensions().disjointTimerQuery)
1580 {
Jamie Madille0472f32018-11-27 16:32:45 -05001581 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001582 return false;
1583 }
1584
Olli Etuaho41997e72016-03-10 13:38:39 +02001585 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001586}
1587
Jamie Madill43da7c42018-08-01 11:34:49 -04001588bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001589{
1590 if (!context->getExtensions().occlusionQueryBoolean &&
1591 !context->getExtensions().disjointTimerQuery)
1592 {
Jamie Madille0472f32018-11-27 16:32:45 -05001593 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001594 return false;
1595 }
1596
Olli Etuaho41997e72016-03-10 13:38:39 +02001597 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001598}
1599
Jamie Madill43da7c42018-08-01 11:34:49 -04001600bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001601{
1602 if (!context->getExtensions().occlusionQueryBoolean &&
1603 !context->getExtensions().disjointTimerQuery)
1604 {
Jamie Madille0472f32018-11-27 16:32:45 -05001605 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Jamie Madillf0e04492017-08-26 15:28:42 -04001606 return false;
1607 }
1608
1609 return true;
1610}
1611
Jamie Madill43da7c42018-08-01 11:34:49 -04001612bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001613{
1614 if (!ValidQueryType(context, target))
1615 {
Jamie Madille0472f32018-11-27 16:32:45 -05001616 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001617 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001618 }
1619
1620 if (id == 0)
1621 {
Jamie Madill610640f2018-11-21 17:28:41 -05001622 context->validationError(GL_INVALID_OPERATION, "Query id is 0");
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001624 }
1625
1626 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1627 // of zero, if the active query object name for <target> is non-zero (for the
1628 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1629 // the active query for either target is non-zero), if <id> is the name of an
1630 // existing query object whose type does not match <target>, or if <id> is the
1631 // active query object name for any query type, the error INVALID_OPERATION is
1632 // generated.
1633
1634 // Ensure no other queries are active
1635 // NOTE: If other queries than occlusion are supported, we will need to check
1636 // separately that:
1637 // a) The query ID passed is not the current active query for any target/type
1638 // b) There are no active queries for the requested target (and in the case
1639 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1640 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001641
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001642 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001643 {
Jamie Madill610640f2018-11-21 17:28:41 -05001644 context->validationError(GL_INVALID_OPERATION, "Other query is active");
Geoff Langb1196682014-07-23 13:47:29 -04001645 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001646 }
1647
1648 Query *queryObject = context->getQuery(id, true, target);
1649
1650 // check that name was obtained with glGenQueries
1651 if (!queryObject)
1652 {
Jamie Madille0472f32018-11-27 16:32:45 -05001653 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001654 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001655 }
1656
1657 // check for type mismatch
1658 if (queryObject->getType() != target)
1659 {
Jamie Madill610640f2018-11-21 17:28:41 -05001660 context->validationError(GL_INVALID_OPERATION, "Query type does not match target");
Geoff Langb1196682014-07-23 13:47:29 -04001661 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001662 }
1663
1664 return true;
1665}
1666
Jamie Madill43da7c42018-08-01 11:34:49 -04001667bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001668{
1669 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001670 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001671 {
Jamie Madille0472f32018-11-27 16:32:45 -05001672 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001673 return false;
1674 }
1675
1676 return ValidateBeginQueryBase(context, target, id);
1677}
1678
Jamie Madill43da7c42018-08-01 11:34:49 -04001679bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001680{
1681 if (!ValidQueryType(context, target))
1682 {
Jamie Madille0472f32018-11-27 16:32:45 -05001683 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001685 }
1686
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001687 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001688
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001689 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001690 {
Jamie Madill610640f2018-11-21 17:28:41 -05001691 context->validationError(GL_INVALID_OPERATION, "Query target not active");
Geoff Langb1196682014-07-23 13:47:29 -04001692 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001693 }
1694
Jamie Madill45c785d2014-05-13 14:09:34 -04001695 return true;
1696}
1697
Jamie Madill43da7c42018-08-01 11:34:49 -04001698bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001699{
1700 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001701 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001702 {
Jamie Madille0472f32018-11-27 16:32:45 -05001703 context->validationError(GL_INVALID_OPERATION, kQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001704 return false;
1705 }
1706
1707 return ValidateEndQueryBase(context, target);
1708}
1709
Corentin Wallezad3ae902018-03-09 13:40:42 -05001710bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001711{
1712 if (!context->getExtensions().disjointTimerQuery)
1713 {
Jamie Madill610640f2018-11-21 17:28:41 -05001714 context->validationError(GL_INVALID_OPERATION, "Disjoint timer query not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001715 return false;
1716 }
1717
Corentin Wallezad3ae902018-03-09 13:40:42 -05001718 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001719 {
Jamie Madille0472f32018-11-27 16:32:45 -05001720 context->validationError(GL_INVALID_ENUM, kInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001721 return false;
1722 }
1723
1724 Query *queryObject = context->getQuery(id, true, target);
1725 if (queryObject == nullptr)
1726 {
Jamie Madille0472f32018-11-27 16:32:45 -05001727 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001728 return false;
1729 }
1730
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001731 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001732 {
Jamie Madille0472f32018-11-27 16:32:45 -05001733 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001734 return false;
1735 }
1736
1737 return true;
1738}
1739
Corentin Wallezad3ae902018-03-09 13:40:42 -05001740bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001741{
Geoff Lang2186c382016-10-14 10:54:54 -04001742 if (numParams)
1743 {
1744 *numParams = 0;
1745 }
1746
Corentin Wallezad3ae902018-03-09 13:40:42 -05001747 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001748 {
Jamie Madille0472f32018-11-27 16:32:45 -05001749 context->validationError(GL_INVALID_ENUM, kInvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001750 return false;
1751 }
1752
1753 switch (pname)
1754 {
1755 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001756 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001757 {
Jamie Madill610640f2018-11-21 17:28:41 -05001758 context->validationError(GL_INVALID_ENUM, "Cannot use current query for timestamp");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001759 return false;
1760 }
1761 break;
1762 case GL_QUERY_COUNTER_BITS_EXT:
1763 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001764 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001765 {
Jamie Madille0472f32018-11-27 16:32:45 -05001766 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001767 return false;
1768 }
1769 break;
1770 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001771 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001772 return false;
1773 }
1774
Geoff Lang2186c382016-10-14 10:54:54 -04001775 if (numParams)
1776 {
1777 // All queries return only one value
1778 *numParams = 1;
1779 }
1780
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001781 return true;
1782}
1783
Corentin Wallezad3ae902018-03-09 13:40:42 -05001784bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001785{
1786 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001787 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001788 {
Jamie Madille0472f32018-11-27 16:32:45 -05001789 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001790 return false;
1791 }
1792
Geoff Lang2186c382016-10-14 10:54:54 -04001793 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001794}
1795
Geoff Lang2186c382016-10-14 10:54:54 -04001796bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001797 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001798 GLenum pname,
1799 GLsizei bufSize,
1800 GLsizei *length,
1801 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001802{
Geoff Lang2186c382016-10-14 10:54:54 -04001803 if (!ValidateRobustEntryPoint(context, bufSize))
1804 {
1805 return false;
1806 }
1807
Brandon Jonesd1049182018-03-28 10:02:20 -07001808 GLsizei numParams = 0;
1809
1810 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001811 {
1812 return false;
1813 }
1814
Brandon Jonesd1049182018-03-28 10:02:20 -07001815 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001816 {
1817 return false;
1818 }
1819
Brandon Jonesd1049182018-03-28 10:02:20 -07001820 SetRobustLengthParam(length, numParams);
1821
Geoff Lang2186c382016-10-14 10:54:54 -04001822 return true;
1823}
1824
1825bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1826{
1827 if (numParams)
1828 {
1829 *numParams = 0;
1830 }
1831
Corentin Wallezad3ae902018-03-09 13:40:42 -05001832 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001833
1834 if (!queryObject)
1835 {
Jamie Madille0472f32018-11-27 16:32:45 -05001836 context->validationError(GL_INVALID_OPERATION, kInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001837 return false;
1838 }
1839
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001840 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001841 {
Jamie Madille0472f32018-11-27 16:32:45 -05001842 context->validationError(GL_INVALID_OPERATION, kQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001843 return false;
1844 }
1845
1846 switch (pname)
1847 {
1848 case GL_QUERY_RESULT_EXT:
1849 case GL_QUERY_RESULT_AVAILABLE_EXT:
1850 break;
1851
1852 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001853 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001854 return false;
1855 }
1856
Geoff Lang2186c382016-10-14 10:54:54 -04001857 if (numParams)
1858 {
1859 *numParams = 1;
1860 }
1861
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001862 return true;
1863}
1864
1865bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1866{
1867 if (!context->getExtensions().disjointTimerQuery)
1868 {
Jamie Madill610640f2018-11-21 17:28:41 -05001869 context->validationError(GL_INVALID_OPERATION, "Timer query extension not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001870 return false;
1871 }
Geoff Lang2186c382016-10-14 10:54:54 -04001872 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1873}
1874
1875bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1876 GLuint id,
1877 GLenum pname,
1878 GLsizei bufSize,
1879 GLsizei *length,
1880 GLint *params)
1881{
1882 if (!context->getExtensions().disjointTimerQuery)
1883 {
Jamie Madill610640f2018-11-21 17:28:41 -05001884 context->validationError(GL_INVALID_OPERATION, "Timer query extension not enabled");
Geoff Lang2186c382016-10-14 10:54:54 -04001885 return false;
1886 }
1887
1888 if (!ValidateRobustEntryPoint(context, bufSize))
1889 {
1890 return false;
1891 }
1892
Brandon Jonesd1049182018-03-28 10:02:20 -07001893 GLsizei numParams = 0;
1894
1895 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001896 {
1897 return false;
1898 }
1899
Brandon Jonesd1049182018-03-28 10:02:20 -07001900 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001901 {
1902 return false;
1903 }
1904
Brandon Jonesd1049182018-03-28 10:02:20 -07001905 SetRobustLengthParam(length, numParams);
1906
Geoff Lang2186c382016-10-14 10:54:54 -04001907 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001908}
1909
1910bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1911{
1912 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001913 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001914 {
Jamie Madille0472f32018-11-27 16:32:45 -05001915 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001916 return false;
1917 }
Geoff Lang2186c382016-10-14 10:54:54 -04001918 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1919}
1920
1921bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1922 GLuint id,
1923 GLenum pname,
1924 GLsizei bufSize,
1925 GLsizei *length,
1926 GLuint *params)
1927{
1928 if (!context->getExtensions().disjointTimerQuery &&
1929 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1930 {
Jamie Madille0472f32018-11-27 16:32:45 -05001931 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001932 return false;
1933 }
1934
1935 if (!ValidateRobustEntryPoint(context, bufSize))
1936 {
1937 return false;
1938 }
1939
Brandon Jonesd1049182018-03-28 10:02:20 -07001940 GLsizei numParams = 0;
1941
1942 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001943 {
1944 return false;
1945 }
1946
Brandon Jonesd1049182018-03-28 10:02:20 -07001947 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001948 {
1949 return false;
1950 }
1951
Brandon Jonesd1049182018-03-28 10:02:20 -07001952 SetRobustLengthParam(length, numParams);
1953
Geoff Lang2186c382016-10-14 10:54:54 -04001954 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001955}
1956
1957bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1958{
1959 if (!context->getExtensions().disjointTimerQuery)
1960 {
Jamie Madille0472f32018-11-27 16:32:45 -05001961 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001962 return false;
1963 }
Geoff Lang2186c382016-10-14 10:54:54 -04001964 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1965}
1966
1967bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1968 GLuint id,
1969 GLenum pname,
1970 GLsizei bufSize,
1971 GLsizei *length,
1972 GLint64 *params)
1973{
1974 if (!context->getExtensions().disjointTimerQuery)
1975 {
Jamie Madille0472f32018-11-27 16:32:45 -05001976 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001977 return false;
1978 }
1979
1980 if (!ValidateRobustEntryPoint(context, bufSize))
1981 {
1982 return false;
1983 }
1984
Brandon Jonesd1049182018-03-28 10:02:20 -07001985 GLsizei numParams = 0;
1986
1987 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001988 {
1989 return false;
1990 }
1991
Brandon Jonesd1049182018-03-28 10:02:20 -07001992 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001993 {
1994 return false;
1995 }
1996
Brandon Jonesd1049182018-03-28 10:02:20 -07001997 SetRobustLengthParam(length, numParams);
1998
Geoff Lang2186c382016-10-14 10:54:54 -04001999 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002000}
2001
2002bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
2003{
2004 if (!context->getExtensions().disjointTimerQuery)
2005 {
Jamie Madille0472f32018-11-27 16:32:45 -05002006 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002007 return false;
2008 }
Geoff Lang2186c382016-10-14 10:54:54 -04002009 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
2010}
2011
2012bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
2013 GLuint id,
2014 GLenum pname,
2015 GLsizei bufSize,
2016 GLsizei *length,
2017 GLuint64 *params)
2018{
2019 if (!context->getExtensions().disjointTimerQuery)
2020 {
Jamie Madille0472f32018-11-27 16:32:45 -05002021 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002022 return false;
2023 }
2024
2025 if (!ValidateRobustEntryPoint(context, bufSize))
2026 {
2027 return false;
2028 }
2029
Brandon Jonesd1049182018-03-28 10:02:20 -07002030 GLsizei numParams = 0;
2031
2032 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002033 {
2034 return false;
2035 }
2036
Brandon Jonesd1049182018-03-28 10:02:20 -07002037 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002038 {
2039 return false;
2040 }
2041
Brandon Jonesd1049182018-03-28 10:02:20 -07002042 SetRobustLengthParam(length, numParams);
2043
Geoff Lang2186c382016-10-14 10:54:54 -04002044 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002045}
2046
Jamie Madill5b772312018-03-08 20:28:32 -05002047bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002048 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002049 GLint location,
2050 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002051 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002052{
Jiajia Qin5451d532017-11-16 17:16:34 +08002053 // TODO(Jiajia): Add image uniform check in future.
2054 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002055 {
Jamie Madille0472f32018-11-27 16:32:45 -05002056 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002057 return false;
2058 }
2059
Jiajia Qin5451d532017-11-16 17:16:34 +08002060 if (!program)
2061 {
Jamie Madille0472f32018-11-27 16:32:45 -05002062 context->validationError(GL_INVALID_OPERATION, kInvalidProgramName);
Jiajia Qin5451d532017-11-16 17:16:34 +08002063 return false;
2064 }
2065
2066 if (!program->isLinked())
2067 {
Jamie Madille0472f32018-11-27 16:32:45 -05002068 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiajia Qin5451d532017-11-16 17:16:34 +08002069 return false;
2070 }
2071
2072 if (location == -1)
2073 {
2074 // Silently ignore the uniform command
2075 return false;
2076 }
2077
2078 const auto &uniformLocations = program->getUniformLocations();
2079 size_t castedLocation = static_cast<size_t>(location);
2080 if (castedLocation >= uniformLocations.size())
2081 {
Jamie Madille0472f32018-11-27 16:32:45 -05002082 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002083 return false;
2084 }
2085
2086 const auto &uniformLocation = uniformLocations[castedLocation];
2087 if (uniformLocation.ignored)
2088 {
2089 // Silently ignore the uniform command
2090 return false;
2091 }
2092
2093 if (!uniformLocation.used())
2094 {
Jamie Madille0472f32018-11-27 16:32:45 -05002095 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002096 return false;
2097 }
2098
2099 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2100
2101 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002102 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002103 {
Jamie Madille0472f32018-11-27 16:32:45 -05002104 context->validationError(GL_INVALID_OPERATION, kInvalidUniformCount);
Jiajia Qin5451d532017-11-16 17:16:34 +08002105 return false;
2106 }
2107
2108 *uniformOut = &uniform;
2109 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002110}
2111
Jamie Madill5b772312018-03-08 20:28:32 -05002112bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002113 GLenum uniformType,
2114 GLsizei count,
2115 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002116{
Jiajia Qin5451d532017-11-16 17:16:34 +08002117 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2118 // It is compatible with INT or BOOL.
2119 // Do these cheap tests first, for a little extra speed.
2120 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002121 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002122 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002123 }
2124
Jiajia Qin5451d532017-11-16 17:16:34 +08002125 if (IsSamplerType(uniformType))
2126 {
2127 // Check that the values are in range.
2128 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2129 for (GLsizei i = 0; i < count; ++i)
2130 {
2131 if (value[i] < 0 || value[i] >= max)
2132 {
Jamie Madill610640f2018-11-21 17:28:41 -05002133 context->validationError(GL_INVALID_VALUE, "sampler uniform value out of range");
Jiajia Qin5451d532017-11-16 17:16:34 +08002134 return false;
2135 }
2136 }
2137 return true;
2138 }
2139
Jamie Madill610640f2018-11-21 17:28:41 -05002140 context->validationError(GL_INVALID_OPERATION, "wrong type of value for uniform");
Jiajia Qin5451d532017-11-16 17:16:34 +08002141 return false;
2142}
2143
Jamie Madill5b772312018-03-08 20:28:32 -05002144bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002145{
2146 // Check that the value type is compatible with uniform type.
2147 if (valueType == uniformType)
2148 {
2149 return true;
2150 }
2151
Jamie Madill610640f2018-11-21 17:28:41 -05002152 context->validationError(GL_INVALID_OPERATION, "wrong type of value for uniform");
Jiajia Qin5451d532017-11-16 17:16:34 +08002153 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002154}
2155
Jamie Madill5b772312018-03-08 20:28:32 -05002156bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002157{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002158 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002159 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002160 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2161 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002162}
2163
Jamie Madill5b772312018-03-08 20:28:32 -05002164bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002165{
2166 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002167 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002168 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2169 ValidateUniform1ivValue(context, uniform->type, count, value);
2170}
2171
Jamie Madill5b772312018-03-08 20:28:32 -05002172bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002173 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002174 GLint location,
2175 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002176 GLboolean transpose)
2177{
Geoff Lang92019432017-11-20 13:09:34 -05002178 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002179 {
Jamie Madille0472f32018-11-27 16:32:45 -05002180 context->validationError(GL_INVALID_VALUE, kES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04002181 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002182 }
2183
Jamie Madill62d31cb2015-09-11 13:25:51 -04002184 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002185 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002186 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2187 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002188}
2189
Jamie Madill5b772312018-03-08 20:28:32 -05002190bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002191{
2192 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2193 {
Jamie Madille0472f32018-11-27 16:32:45 -05002194 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langb1196682014-07-23 13:47:29 -04002195 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002196 }
2197
Jamie Madill0af26e12015-03-05 19:54:33 -05002198 const Caps &caps = context->getCaps();
2199
Jamie Madill893ab082014-05-16 16:56:10 -04002200 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2201 {
2202 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2203
Jamie Madill0af26e12015-03-05 19:54:33 -05002204 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002205 {
Jamie Madille0472f32018-11-27 16:32:45 -05002206 context->validationError(GL_INVALID_OPERATION, kIndexExceedsMaxDrawBuffer);
Geoff Langb1196682014-07-23 13:47:29 -04002207 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002208 }
2209 }
2210
2211 switch (pname)
2212 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002213 case GL_TEXTURE_BINDING_2D:
2214 case GL_TEXTURE_BINDING_CUBE_MAP:
2215 case GL_TEXTURE_BINDING_3D:
2216 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002217 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002218 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002219 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002220 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002221 {
Jamie Madille0472f32018-11-27 16:32:45 -05002222 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03002223 return false;
2224 }
2225 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002226 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2227 if (!context->getExtensions().textureRectangle)
2228 {
Jamie Madill610640f2018-11-21 17:28:41 -05002229 context->validationError(GL_INVALID_ENUM,
2230 "ANGLE_texture_rectangle extension not present");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002231 return false;
2232 }
2233 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002234 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2235 if (!context->getExtensions().eglStreamConsumerExternal &&
2236 !context->getExtensions().eglImageExternal)
2237 {
Jamie Madill610640f2018-11-21 17:28:41 -05002238 context->validationError(GL_INVALID_ENUM,
2239 "Neither NV_EGL_stream_consumer_external "
2240 "nor GL_OES_EGL_image_external "
2241 "extensions enabled");
He Yunchaoced53ae2016-11-29 15:00:51 +08002242 return false;
2243 }
2244 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002245
He Yunchaoced53ae2016-11-29 15:00:51 +08002246 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2247 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002248 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002249 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2250 ASSERT(readFramebuffer);
2251
Jamie Madill610640f2018-11-21 17:28:41 -05002252 if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002253 {
Geoff Langb1196682014-07-23 13:47:29 -04002254 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002255 }
2256
Jamie Madille98b1b52018-03-08 09:47:23 -05002257 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002258 {
Jamie Madille0472f32018-11-27 16:32:45 -05002259 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002260 return false;
2261 }
2262
Jamie Madille98b1b52018-03-08 09:47:23 -05002263 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002264 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002265 {
Jamie Madille0472f32018-11-27 16:32:45 -05002266 context->validationError(GL_INVALID_OPERATION, kReadBufferNotAttached);
Geoff Langb1196682014-07-23 13:47:29 -04002267 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002268 }
2269 }
2270 break;
2271
He Yunchaoced53ae2016-11-29 15:00:51 +08002272 default:
2273 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002274 }
2275
2276 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002277 if (*numParams == 0)
2278 {
2279 return false;
2280 }
2281
2282 return true;
2283}
2284
Brandon Jonesd1049182018-03-28 10:02:20 -07002285bool ValidateGetBooleanvRobustANGLE(Context *context,
2286 GLenum pname,
2287 GLsizei bufSize,
2288 GLsizei *length,
2289 GLboolean *params)
2290{
2291 GLenum nativeType;
2292 unsigned int numParams = 0;
2293
2294 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2295 {
2296 return false;
2297 }
2298
2299 SetRobustLengthParam(length, numParams);
2300
2301 return true;
2302}
2303
2304bool ValidateGetFloatvRobustANGLE(Context *context,
2305 GLenum pname,
2306 GLsizei bufSize,
2307 GLsizei *length,
2308 GLfloat *params)
2309{
2310 GLenum nativeType;
2311 unsigned int numParams = 0;
2312
2313 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2314 {
2315 return false;
2316 }
2317
2318 SetRobustLengthParam(length, numParams);
2319
2320 return true;
2321}
2322
2323bool ValidateGetIntegervRobustANGLE(Context *context,
2324 GLenum pname,
2325 GLsizei bufSize,
2326 GLsizei *length,
2327 GLint *data)
2328{
2329 GLenum nativeType;
2330 unsigned int numParams = 0;
2331
2332 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2333 {
2334 return false;
2335 }
2336
2337 SetRobustLengthParam(length, numParams);
2338
2339 return true;
2340}
2341
2342bool ValidateGetInteger64vRobustANGLE(Context *context,
2343 GLenum pname,
2344 GLsizei bufSize,
2345 GLsizei *length,
2346 GLint64 *data)
2347{
2348 GLenum nativeType;
2349 unsigned int numParams = 0;
2350
2351 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2352 {
2353 return false;
2354 }
2355
2356 if (nativeType == GL_INT_64_ANGLEX)
2357 {
2358 CastStateValues(context, nativeType, pname, numParams, data);
2359 return false;
2360 }
2361
2362 SetRobustLengthParam(length, numParams);
2363 return true;
2364}
2365
Jamie Madill5b772312018-03-08 20:28:32 -05002366bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002367 GLenum pname,
2368 GLsizei bufSize,
2369 GLenum *nativeType,
2370 unsigned int *numParams)
2371{
2372 if (!ValidateRobustEntryPoint(context, bufSize))
2373 {
2374 return false;
2375 }
2376
2377 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2378 {
2379 return false;
2380 }
2381
2382 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002383 {
2384 return false;
2385 }
2386
2387 return true;
2388}
2389
Jamie Madill5b772312018-03-08 20:28:32 -05002390bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002391 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002392 GLint level,
2393 GLenum internalformat,
2394 bool isSubImage,
2395 GLint xoffset,
2396 GLint yoffset,
2397 GLint zoffset,
2398 GLint x,
2399 GLint y,
2400 GLsizei width,
2401 GLsizei height,
2402 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002403 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002404{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002405 TextureType texType = TextureTargetToType(target);
2406
Brandon Jones6cad5662017-06-14 13:25:13 -07002407 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002408 {
Jamie Madille0472f32018-11-27 16:32:45 -05002409 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07002410 return false;
2411 }
2412
2413 if (width < 0 || height < 0)
2414 {
Jamie Madille0472f32018-11-27 16:32:45 -05002415 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002416 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002417 }
2418
He Yunchaoced53ae2016-11-29 15:00:51 +08002419 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2420 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002421 {
Jamie Madille0472f32018-11-27 16:32:45 -05002422 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002423 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002424 }
2425
2426 if (border != 0)
2427 {
Jamie Madille0472f32018-11-27 16:32:45 -05002428 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002429 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002430 }
2431
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002432 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002433 {
Jamie Madille0472f32018-11-27 16:32:45 -05002434 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002435 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002436 }
2437
Jamie Madill43da7c42018-08-01 11:34:49 -04002438 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002439 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002440 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002441 {
Geoff Langb1196682014-07-23 13:47:29 -04002442 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002443 }
2444
Jamie Madille98b1b52018-03-08 09:47:23 -05002445 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002446 {
Geoff Langb1196682014-07-23 13:47:29 -04002447 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002448 }
2449
Martin Radev138064f2016-07-15 12:03:41 +03002450 if (readFramebuffer->getReadBufferState() == GL_NONE)
2451 {
Jamie Madille0472f32018-11-27 16:32:45 -05002452 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002453 return false;
2454 }
2455
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002456 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2457 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002458 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002459 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002460 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2461 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002462 {
Jamie Madille0472f32018-11-27 16:32:45 -05002463 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002464 return false;
2465 }
2466
Martin Radev04e2c3b2017-07-27 16:54:35 +03002467 // ANGLE_multiview spec, Revision 1:
2468 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2469 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002470 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2471 // framebuffer is more than one.
2472 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002473 {
Jamie Madill610640f2018-11-21 17:28:41 -05002474 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
2475 "The active read framebuffer object has multiview attachments.");
Martin Radev04e2c3b2017-07-27 16:54:35 +03002476 return false;
2477 }
2478
Jamie Madill43da7c42018-08-01 11:34:49 -04002479 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002480
Geoff Langaae65a42014-05-26 12:43:44 -04002481 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002482 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002483 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002484 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002485 maxDimension = caps.max2DTextureSize;
2486 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002487
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002488 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002489 maxDimension = caps.maxCubeMapTextureSize;
2490 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002491
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002492 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002493 maxDimension = caps.maxRectangleTextureSize;
2494 break;
2495
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002496 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002497 maxDimension = caps.max2DTextureSize;
2498 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002499
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002500 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002501 maxDimension = caps.max3DTextureSize;
2502 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002503
He Yunchaoced53ae2016-11-29 15:00:51 +08002504 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002505 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002506 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002507 }
2508
Jamie Madill43da7c42018-08-01 11:34:49 -04002509 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002510 if (!texture)
2511 {
Jamie Madille0472f32018-11-27 16:32:45 -05002512 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002513 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002514 }
2515
Geoff Lang69cce582015-09-17 13:20:36 -04002516 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002517 {
Jamie Madille0472f32018-11-27 16:32:45 -05002518 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002519 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002520 }
2521
Jamie Madill43da7c42018-08-01 11:34:49 -04002522 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002523 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002524 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002525
Geoff Lang966c9402017-04-18 12:38:27 -04002526 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002527 {
Jamie Madille0472f32018-11-27 16:32:45 -05002528 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Langa9be0dc2014-12-17 12:34:40 -05002529 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002530 }
2531
2532 if (isSubImage)
2533 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002534 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2535 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2536 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002537 {
Jamie Madille0472f32018-11-27 16:32:45 -05002538 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002539 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002540 }
2541 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002542 else
2543 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002544 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002545 {
Jamie Madille0472f32018-11-27 16:32:45 -05002546 context->validationError(GL_INVALID_VALUE, kCubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002547 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002548 }
2549
Geoff Langeb66a6e2016-10-31 13:06:12 -04002550 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002551 {
Jamie Madille0472f32018-11-27 16:32:45 -05002552 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002553 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002554 }
2555
2556 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002557 if (static_cast<int>(width) > maxLevelDimension ||
2558 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002559 {
Jamie Madille0472f32018-11-27 16:32:45 -05002560 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002561 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002562 }
2563 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002564
Jamie Madill0c8abca2016-07-22 20:21:26 -04002565 if (textureFormatOut)
2566 {
2567 *textureFormatOut = texture->getFormat(target, level);
2568 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002569
2570 // Detect texture copying feedback loops for WebGL.
2571 if (context->getExtensions().webglCompatibility)
2572 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002573 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002574 {
Jamie Madille0472f32018-11-27 16:32:45 -05002575 context->validationError(GL_INVALID_OPERATION, kFeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002576 return false;
2577 }
2578 }
2579
Jamie Madill560a8d82014-05-21 13:06:20 -04002580 return true;
2581}
2582
Jamie Madillb42162f2018-08-20 12:58:37 -04002583// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2584// completeness check.
2585const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002586{
2587 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002588 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002589
2590 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2591 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2592 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002593 VertexArray *vertexArray = state.getVertexArray();
2594 ASSERT(vertexArray);
2595
2596 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002597 {
Jamie Madille0472f32018-11-27 16:32:45 -05002598 return kBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002599 }
2600
2601 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2602 // Section 6.10 of the WebGL 1.0 spec.
2603 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002604 ASSERT(framebuffer);
2605
Jamie Madille7d80f32018-08-08 15:49:23 -04002606 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2607 {
2608 ASSERT(framebuffer);
2609 const FramebufferAttachment *dsAttachment =
2610 framebuffer->getStencilOrDepthStencilAttachment();
2611 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2612 ASSERT(stencilBits <= 8);
2613
2614 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2615 if (depthStencilState.stencilTest && stencilBits > 0)
2616 {
2617 GLuint maxStencilValue = (1 << stencilBits) - 1;
2618
2619 bool differentRefs =
2620 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2621 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2622 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2623 (depthStencilState.stencilBackWritemask & maxStencilValue);
2624 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2625 (depthStencilState.stencilBackMask & maxStencilValue);
2626
2627 if (differentRefs || differentWritemasks || differentMasks)
2628 {
2629 if (!extensions.webglCompatibility)
2630 {
2631 WARN() << "This ANGLE implementation does not support separate front/back "
2632 "stencil writemasks, reference values, or stencil mask values.";
2633 }
Jamie Madille0472f32018-11-27 16:32:45 -05002634 return kStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002635 }
2636 }
2637 }
2638
2639 if (!framebuffer->isComplete(context))
2640 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002641 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
Jamie Madille0472f32018-11-27 16:32:45 -05002642 return kDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002643 }
2644
2645 if (context->getStateCache().hasAnyEnabledClientAttrib())
2646 {
2647 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2648 {
2649 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2650 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2651 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2652 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madille0472f32018-11-27 16:32:45 -05002653 return kVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002654 }
2655
2656 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2657 {
2658 // This is an application error that would normally result in a crash, but we catch it
2659 // and return an error
Jamie Madille0472f32018-11-27 16:32:45 -05002660 return kVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002661 }
2662 }
2663
2664 // If we are running GLES1, there is no current program.
2665 if (context->getClientVersion() >= Version(2, 0))
2666 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002667 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002668 if (!program)
2669 {
Jamie Madille0472f32018-11-27 16:32:45 -05002670 return kProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002671 }
2672
2673 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2674 // vertex shader stage or fragment shader stage is a undefined behaviour.
2675 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2676 // produce undefined result.
2677 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2678 !program->hasLinkedShaderStage(ShaderType::Fragment))
2679 {
Jamie Madille0472f32018-11-27 16:32:45 -05002680 return kNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002681 }
2682
2683 if (!program->validateSamplers(nullptr, context->getCaps()))
2684 {
Jamie Madille0472f32018-11-27 16:32:45 -05002685 return kTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002686 }
2687
2688 if (extensions.multiview)
2689 {
2690 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2691 const int framebufferNumViews = framebuffer->getNumViews();
2692 if (framebufferNumViews != programNumViews)
2693 {
Jamie Madille0472f32018-11-27 16:32:45 -05002694 return kMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002695 }
2696
2697 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2698 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2699 framebufferNumViews > 1)
2700 {
Jamie Madille0472f32018-11-27 16:32:45 -05002701 return kMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002702 }
2703
2704 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2705 state.isQueryActive(QueryType::TimeElapsed))
2706 {
Jamie Madille0472f32018-11-27 16:32:45 -05002707 return kMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002708 }
2709 }
2710
2711 // Uniform buffer validation
2712 for (unsigned int uniformBlockIndex = 0;
2713 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2714 {
2715 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002716 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002717 const OffsetBindingPointer<Buffer> &uniformBuffer =
2718 state.getIndexedUniformBuffer(blockBinding);
2719
2720 if (uniformBuffer.get() == nullptr)
2721 {
2722 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002723 return kUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002724 }
2725
2726 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2727 if (uniformBufferSize < uniformBlock.dataSize)
2728 {
2729 // undefined behaviour
Jamie Madille0472f32018-11-27 16:32:45 -05002730 return kUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002731 }
2732
2733 if (extensions.webglCompatibility &&
2734 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2735 {
Jamie Madille0472f32018-11-27 16:32:45 -05002736 return kUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002737 }
2738 }
2739
2740 // Do some additonal WebGL-specific validation
2741 if (extensions.webglCompatibility)
2742 {
2743 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2744 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2745 transformFeedbackObject->buffersBoundForOtherUse())
2746 {
Jamie Madille0472f32018-11-27 16:32:45 -05002747 return kTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002748 }
2749
2750 // Detect rendering feedback loops for WebGL.
2751 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2752 {
Jamie Madille0472f32018-11-27 16:32:45 -05002753 return kFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002754 }
2755
2756 // Detect that the vertex shader input types match the attribute types
2757 if (!ValidateVertexShaderAttributeTypeMatch(context))
2758 {
Jamie Madille0472f32018-11-27 16:32:45 -05002759 return kVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002760 }
2761
2762 // Detect that the color buffer types match the fragment shader output types
2763 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2764 {
Jamie Madille0472f32018-11-27 16:32:45 -05002765 return kDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002766 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002767
2768 const VertexArray *vao = context->getGLState().getVertexArray();
2769 if (vao->hasTransformFeedbackBindingConflict(context))
2770 {
Jamie Madille0472f32018-11-27 16:32:45 -05002771 return kVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002772 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002773 }
2774 }
2775
Jamie Madillb42162f2018-08-20 12:58:37 -04002776 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002777}
2778
Jamie Madill16e28fd2018-09-12 11:03:05 -04002779bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002780{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002781 const Extensions &extensions = context->getExtensions();
2782
Jamie Madill1aeb1312014-06-20 13:21:25 -04002783 switch (mode)
2784 {
Jamie Madill493f9572018-05-24 19:52:15 -04002785 case PrimitiveMode::Points:
2786 case PrimitiveMode::Lines:
2787 case PrimitiveMode::LineLoop:
2788 case PrimitiveMode::LineStrip:
2789 case PrimitiveMode::Triangles:
2790 case PrimitiveMode::TriangleStrip:
2791 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002792 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002793
Jamie Madill493f9572018-05-24 19:52:15 -04002794 case PrimitiveMode::LinesAdjacency:
2795 case PrimitiveMode::LineStripAdjacency:
2796 case PrimitiveMode::TrianglesAdjacency:
2797 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002798 if (!extensions.geometryShader)
2799 {
Jamie Madille0472f32018-11-27 16:32:45 -05002800 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaofccebff2018-03-08 13:51:02 +08002801 return false;
2802 }
2803 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002804 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002805 context->validationError(GL_INVALID_ENUM, kInvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002806 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002807 }
2808
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002809 // If we are running GLES1, there is no current program.
2810 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002811 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002812 const State &state = context->getGLState();
2813
Jamie Madill785e8a02018-10-04 17:42:00 -04002814 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002815 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002816
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002817 // Do geometry shader specific validations
2818 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002819 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002820 if (!IsCompatibleDrawModeWithGeometryShader(
2821 mode, program->getGeometryShaderInputPrimitiveType()))
2822 {
Jamie Madill610640f2018-11-21 17:28:41 -05002823 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002824 kIncompatibleDrawModeAgainstGeometryShader);
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002825 return false;
2826 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002827 }
2828 }
2829
Jamie Madill9fdaa492018-02-16 10:52:11 -05002830 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002831}
2832
Jamie Madill16e28fd2018-09-12 11:03:05 -04002833bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
2834{
2835 if (!context->getStateCache().isValidDrawMode(mode))
2836 {
2837 return ValidateDrawMode(context, mode);
2838 }
2839
2840 if (count < 0)
2841 {
Jamie Madille0472f32018-11-27 16:32:45 -05002842 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002843 return false;
2844 }
2845
2846 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2847 if (drawStatesError)
2848 {
2849 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2850
2851 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2852 // Incomplete.
2853 GLenum errorCode =
Jamie Madille0472f32018-11-27 16:32:45 -05002854 (errorMessage == kDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2855 : GL_INVALID_OPERATION);
Jamie Madill610640f2018-11-21 17:28:41 -05002856 context->validationError(errorCode, errorMessage);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002857 return false;
2858 }
2859
2860 return true;
2861}
2862
Jamie Madill5b772312018-03-08 20:28:32 -05002863bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002864 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002865 GLint first,
2866 GLsizei count,
2867 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002868{
Jamie Madillfd716582014-06-06 17:09:04 -04002869 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002870 {
Jamie Madille0472f32018-11-27 16:32:45 -05002871 context->validationError(GL_INVALID_VALUE, kNegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002872 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002873 }
2874
Jamie Madill16e28fd2018-09-12 11:03:05 -04002875 if (count < 0)
2876 {
Jamie Madille0472f32018-11-27 16:32:45 -05002877 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002878 return false;
2879 }
2880
Jamie Madill7f232932018-09-12 11:03:06 -04002881 const State &state = context->getGLState();
2882 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002883 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002884 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002885 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002886 if (!ValidateTransformFeedbackPrimitiveMode(context,
2887 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002888 {
Jamie Madille0472f32018-11-27 16:32:45 -05002889 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
James Darpinian30b604d2018-03-12 17:26:57 -07002890 return false;
2891 }
2892
2893 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2894 {
Jamie Madille0472f32018-11-27 16:32:45 -05002895 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackBufferTooSmall);
James Darpinian30b604d2018-03-12 17:26:57 -07002896 return false;
2897 }
Jamie Madillfd716582014-06-06 17:09:04 -04002898 }
2899
Jamie Madill16e28fd2018-09-12 11:03:05 -04002900 if (!context->getStateCache().isValidDrawMode(mode))
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002901 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002902 return ValidateDrawMode(context, mode);
2903 }
2904
2905 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2906 if (drawStatesError)
2907 {
2908 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2909
2910 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2911 // Incomplete.
2912 GLenum errorCode =
Jamie Madille0472f32018-11-27 16:32:45 -05002913 (errorMessage == kDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2914 : GL_INVALID_OPERATION);
Jamie Madill610640f2018-11-21 17:28:41 -05002915 context->validationError(errorCode, errorMessage);
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002916 return false;
2917 }
2918
Corentin Wallez71168a02016-12-19 15:11:18 -08002919 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002920 // - first < 0 has been checked as an error condition.
2921 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002922 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002923 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002924 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002925 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002926 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2927 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2928 {
Jamie Madille0472f32018-11-27 16:32:45 -05002929 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madill9fdaa492018-02-16 10:52:11 -05002930 return false;
2931 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002932
Jamie Madill2da53562018-08-01 11:34:47 -04002933 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002934 {
2935 return false;
2936 }
Jamie Madillfd716582014-06-06 17:09:04 -04002937 }
2938
2939 return true;
2940}
2941
He Yunchaoced53ae2016-11-29 15:00:51 +08002942bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002943 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002944 GLint first,
2945 GLsizei count,
2946 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002947{
Geoff Lang63c5a592017-09-27 14:08:16 -04002948 if (!context->getExtensions().instancedArrays)
2949 {
Jamie Madille0472f32018-11-27 16:32:45 -05002950 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002951 return false;
2952 }
2953
Corentin Wallez170efbf2017-05-02 13:45:01 -04002954 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002955 {
2956 return false;
2957 }
2958
Corentin Wallez0dc97812017-06-22 14:38:44 -04002959 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002960}
2961
Jamie Madill493f9572018-05-24 19:52:15 -04002962bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, GLenum type)
Jamie Madillfd716582014-06-06 17:09:04 -04002963{
Jamie Madill250d33f2014-06-06 17:09:03 -04002964 switch (type)
2965 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002966 case GL_UNSIGNED_BYTE:
2967 case GL_UNSIGNED_SHORT:
2968 break;
2969 case GL_UNSIGNED_INT:
2970 if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
2971 {
Jamie Madille0472f32018-11-27 16:32:45 -05002972 context->validationError(GL_INVALID_ENUM, kTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002973 return false;
2974 }
2975 break;
2976 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002977 context->validationError(GL_INVALID_ENUM, kTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002978 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002979 }
2980
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002981 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002982
Jamie Madill43da7c42018-08-01 11:34:49 -04002983 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002984 if (curTransformFeedback && curTransformFeedback->isActive() &&
2985 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002986 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002987 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2988 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2989 if (context->getExtensions().geometryShader)
2990 {
2991 if (!ValidateTransformFeedbackPrimitiveMode(
2992 context, curTransformFeedback->getPrimitiveMode(), mode))
2993 {
Jamie Madille0472f32018-11-27 16:32:45 -05002994 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002995 return false;
2996 }
2997 }
2998 else
2999 {
3000 // It is an invalid operation to call DrawElements, DrawRangeElements or
3001 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
3002 // 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003003 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05003004 kUnsupportedDrawModeForTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003005 return false;
3006 }
Jamie Madill250d33f2014-06-06 17:09:03 -04003007 }
3008
Jiajia Qind9671222016-11-29 16:30:31 +08003009 return true;
3010}
3011
Jamie Madill5b772312018-03-08 20:28:32 -05003012bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003013 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003014 GLsizei count,
3015 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003016 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003017 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08003018{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003019 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003020 return false;
3021
3022 const State &state = context->getGLState();
3023
Corentin Wallez170efbf2017-05-02 13:45:01 -04003024 if (!ValidateDrawBase(context, mode, count))
3025 {
3026 return false;
3027 }
3028
Jamie Madill43da7c42018-08-01 11:34:49 -04003029 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003030 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003031
Jamie Madill43da7c42018-08-01 11:34:49 -04003032 GLuint typeBytes = GetTypeInfo(type).bytes;
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003033 ASSERT(isPow2(typeBytes) && typeBytes > 0);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003034
3035 if (context->getExtensions().webglCompatibility)
3036 {
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003037 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3038 {
3039 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3040 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3041 // data type passed to the call, or an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003042 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003043 return false;
3044 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003045
3046 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3047 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3048 // error is generated.
3049 if (reinterpret_cast<intptr_t>(indices) < 0)
3050 {
Jamie Madille0472f32018-11-27 16:32:45 -05003051 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003052 return false;
3053 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003054
Brandon Jones2a018152018-06-08 15:59:26 -07003055 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003056 {
3057 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003058 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3059 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003060 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003061 return false;
3062 }
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003063
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003064 if (elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
James Darpiniane8a93c62018-01-04 18:02:24 -08003065 {
Jamie Madill610640f2018-11-21 17:28:41 -05003066 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05003067 kElementArrayBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003068 return false;
3069 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003070 }
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003071 else
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003072 {
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003073 if (elementArrayBuffer)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003074 {
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003075 if (elementArrayBuffer->isMapped())
3076 {
3077 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3078 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the
3079 // WebGL 2.0 API. https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
3080 context->validationError(GL_INVALID_OPERATION, "Index buffer is mapped.");
3081 return false;
3082 }
3083 }
3084 else if (!context->getGLState().areClientArraysEnabled())
3085 {
3086 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003087 return false;
3088 }
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003089 }
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003090
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003091 if (count > 0)
3092 {
3093 if (!elementArrayBuffer)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003094 {
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003095 if (!indices)
3096 {
3097 // This is an application error that would normally result in a crash, but we catch
3098 // it and return an error
3099 context->validationError(GL_INVALID_OPERATION,
3100 "No element array buffer and no pointer.");
3101 return false;
3102 }
3103 }
3104 else
3105 {
3106 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3107 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3108 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3109 constexpr uint64_t kMaxTypeSize = 8;
3110 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3111 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3112 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3113
3114 uint64_t typeSize = typeBytes;
3115 uint64_t elementCount = static_cast<uint64_t>(count);
3116 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3117
3118 // Doing the multiplication here is overflow-safe
3119 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3120
3121 // The offset can be any value, check for overflows
3122 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3123 if (elementDataSizeNoOffset > kUint64Max - offset)
3124 {
3125 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
3126 return false;
3127 }
3128
3129 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3130 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
3131 {
3132 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
3133 return false;
3134 }
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003135 }
3136
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003137 if (!context->getExtensions().robustBufferAccessBehavior && primcount > 0)
3138 {
3139 // Use the parameter buffer to retrieve and cache the index range.
3140 IndexRange indexRange;
3141 ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
3142
3143 // If we use an index greater than our maximum supported index range, return an error.
3144 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
3145 // always return an error if possible here.
3146 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
3147 {
3148 context->validationError(GL_INVALID_OPERATION, kExceedsMaxElement);
3149 return false;
3150 }
3151
3152 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
3153 {
3154 return false;
3155 }
3156
3157 // No op if there are no real indices in the index data (all are primitive restart).
3158 return (indexRange.vertexIndexCount > 0);
3159 }
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003160 }
3161
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003162 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003163}
3164
Jamie Madill5b772312018-03-08 20:28:32 -05003165bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003166 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003167 GLsizei count,
3168 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003169 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003170 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003171{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003172 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003173}
3174
Geoff Lang3edfe032015-09-04 16:38:24 -04003175bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003176 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003177 GLsizei count,
3178 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003179 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003180 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003181{
Geoff Lang63c5a592017-09-27 14:08:16 -04003182 if (!context->getExtensions().instancedArrays)
3183 {
Jamie Madille0472f32018-11-27 16:32:45 -05003184 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04003185 return false;
3186 }
3187
Corentin Wallez170efbf2017-05-02 13:45:01 -04003188 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003189 {
3190 return false;
3191 }
3192
Corentin Wallez0dc97812017-06-22 14:38:44 -04003193 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003194}
3195
He Yunchaoced53ae2016-11-29 15:00:51 +08003196bool ValidateFramebufferTextureBase(Context *context,
3197 GLenum target,
3198 GLenum attachment,
3199 GLuint texture,
3200 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003201{
Geoff Lange8afa902017-09-27 15:00:43 -04003202 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003203 {
Jamie Madille0472f32018-11-27 16:32:45 -05003204 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003205 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003206 }
3207
3208 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003209 {
3210 return false;
3211 }
3212
Jamie Madill55ec3b12014-07-03 10:38:57 -04003213 if (texture != 0)
3214 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003215 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003216
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003217 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003218 {
Jamie Madille0472f32018-11-27 16:32:45 -05003219 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04003220 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003221 }
3222
3223 if (level < 0)
3224 {
Jamie Madille0472f32018-11-27 16:32:45 -05003225 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04003226 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003227 }
3228 }
3229
Jamie Madill43da7c42018-08-01 11:34:49 -04003230 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003231 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003232
Jamie Madill84115c92015-04-23 15:00:07 -04003233 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003234 {
Jamie Madille0472f32018-11-27 16:32:45 -05003235 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003236 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003237 }
3238
3239 return true;
3240}
3241
Geoff Langb1196682014-07-23 13:47:29 -04003242bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003243{
3244 if (program == 0)
3245 {
Jamie Madille0472f32018-11-27 16:32:45 -05003246 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04003247 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003248 }
3249
Jamie Madill43da7c42018-08-01 11:34:49 -04003250 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003251 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003252 {
3253 return false;
3254 }
3255
Jamie Madill0063c512014-08-25 15:47:53 -04003256 if (!programObject || !programObject->isLinked())
3257 {
Jamie Madille0472f32018-11-27 16:32:45 -05003258 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003259 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003260 }
3261
Geoff Lang7dd2e102014-11-10 15:19:26 -05003262 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003263 {
Jamie Madille0472f32018-11-27 16:32:45 -05003264 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003265 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003266 }
3267
Jamie Madill0063c512014-08-25 15:47:53 -04003268 return true;
3269}
3270
Geoff Langf41d0ee2016-10-07 13:04:23 -04003271static bool ValidateSizedGetUniform(Context *context,
3272 GLuint program,
3273 GLint location,
3274 GLsizei bufSize,
3275 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003276{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003277 if (length)
3278 {
3279 *length = 0;
3280 }
3281
Jamie Madill78f41802014-08-25 15:47:55 -04003282 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003283 {
Jamie Madill78f41802014-08-25 15:47:55 -04003284 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003285 }
3286
Geoff Langf41d0ee2016-10-07 13:04:23 -04003287 if (bufSize < 0)
3288 {
Jamie Madille0472f32018-11-27 16:32:45 -05003289 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003290 return false;
3291 }
3292
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003293 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003294 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003295
Jamie Madill78f41802014-08-25 15:47:55 -04003296 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003297 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003298 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003299 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003300 {
Jamie Madille0472f32018-11-27 16:32:45 -05003301 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003302 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003303 }
3304
Geoff Langf41d0ee2016-10-07 13:04:23 -04003305 if (length)
3306 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003307 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003308 }
3309
Jamie Madill0063c512014-08-25 15:47:53 -04003310 return true;
3311}
3312
He Yunchaoced53ae2016-11-29 15:00:51 +08003313bool ValidateGetnUniformfvEXT(Context *context,
3314 GLuint program,
3315 GLint location,
3316 GLsizei bufSize,
3317 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003318{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003319 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003320}
3321
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003322bool ValidateGetnUniformfvRobustANGLE(Context *context,
3323 GLuint program,
3324 GLint location,
3325 GLsizei bufSize,
3326 GLsizei *length,
3327 GLfloat *params)
3328{
3329 UNIMPLEMENTED();
3330 return false;
3331}
3332
He Yunchaoced53ae2016-11-29 15:00:51 +08003333bool ValidateGetnUniformivEXT(Context *context,
3334 GLuint program,
3335 GLint location,
3336 GLsizei bufSize,
3337 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003338{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003339 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3340}
3341
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003342bool ValidateGetnUniformivRobustANGLE(Context *context,
3343 GLuint program,
3344 GLint location,
3345 GLsizei bufSize,
3346 GLsizei *length,
3347 GLint *params)
3348{
3349 UNIMPLEMENTED();
3350 return false;
3351}
3352
3353bool ValidateGetnUniformuivRobustANGLE(Context *context,
3354 GLuint program,
3355 GLint location,
3356 GLsizei bufSize,
3357 GLsizei *length,
3358 GLuint *params)
3359{
3360 UNIMPLEMENTED();
3361 return false;
3362}
3363
Geoff Langf41d0ee2016-10-07 13:04:23 -04003364bool ValidateGetUniformfvRobustANGLE(Context *context,
3365 GLuint program,
3366 GLint location,
3367 GLsizei bufSize,
3368 GLsizei *length,
3369 GLfloat *params)
3370{
3371 if (!ValidateRobustEntryPoint(context, bufSize))
3372 {
3373 return false;
3374 }
3375
Brandon Jonesd1049182018-03-28 10:02:20 -07003376 GLsizei writeLength = 0;
3377
Geoff Langf41d0ee2016-10-07 13:04:23 -04003378 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003379 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3380 {
3381 return false;
3382 }
3383
3384 SetRobustLengthParam(length, writeLength);
3385
3386 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003387}
3388
3389bool ValidateGetUniformivRobustANGLE(Context *context,
3390 GLuint program,
3391 GLint location,
3392 GLsizei bufSize,
3393 GLsizei *length,
3394 GLint *params)
3395{
3396 if (!ValidateRobustEntryPoint(context, bufSize))
3397 {
3398 return false;
3399 }
3400
Brandon Jonesd1049182018-03-28 10:02:20 -07003401 GLsizei writeLength = 0;
3402
Geoff Langf41d0ee2016-10-07 13:04:23 -04003403 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003404 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3405 {
3406 return false;
3407 }
3408
3409 SetRobustLengthParam(length, writeLength);
3410
3411 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003412}
3413
3414bool ValidateGetUniformuivRobustANGLE(Context *context,
3415 GLuint program,
3416 GLint location,
3417 GLsizei bufSize,
3418 GLsizei *length,
3419 GLuint *params)
3420{
3421 if (!ValidateRobustEntryPoint(context, bufSize))
3422 {
3423 return false;
3424 }
3425
3426 if (context->getClientMajorVersion() < 3)
3427 {
Jamie Madille0472f32018-11-27 16:32:45 -05003428 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003429 return false;
3430 }
3431
Brandon Jonesd1049182018-03-28 10:02:20 -07003432 GLsizei writeLength = 0;
3433
Geoff Langf41d0ee2016-10-07 13:04:23 -04003434 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003435 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3436 {
3437 return false;
3438 }
3439
3440 SetRobustLengthParam(length, writeLength);
3441
3442 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003443}
3444
He Yunchaoced53ae2016-11-29 15:00:51 +08003445bool ValidateDiscardFramebufferBase(Context *context,
3446 GLenum target,
3447 GLsizei numAttachments,
3448 const GLenum *attachments,
3449 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003450{
3451 if (numAttachments < 0)
3452 {
Jamie Madille0472f32018-11-27 16:32:45 -05003453 context->validationError(GL_INVALID_VALUE, kNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003454 return false;
3455 }
3456
3457 for (GLsizei i = 0; i < numAttachments; ++i)
3458 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003459 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003460 {
3461 if (defaultFramebuffer)
3462 {
Jamie Madille0472f32018-11-27 16:32:45 -05003463 context->validationError(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003464 return false;
3465 }
3466
3467 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3468 {
Jamie Madill610640f2018-11-21 17:28:41 -05003469 context->validationError(GL_INVALID_OPERATION,
3470 "Requested color attachment is "
3471 "greater than the maximum supported "
3472 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003473 return false;
3474 }
3475 }
3476 else
3477 {
3478 switch (attachments[i])
3479 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003480 case GL_DEPTH_ATTACHMENT:
3481 case GL_STENCIL_ATTACHMENT:
3482 case GL_DEPTH_STENCIL_ATTACHMENT:
3483 if (defaultFramebuffer)
3484 {
Jamie Madill610640f2018-11-21 17:28:41 -05003485 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003486 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003487 return false;
3488 }
3489 break;
3490 case GL_COLOR:
3491 case GL_DEPTH:
3492 case GL_STENCIL:
3493 if (!defaultFramebuffer)
3494 {
Jamie Madill610640f2018-11-21 17:28:41 -05003495 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003496 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003497 return false;
3498 }
3499 break;
3500 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003501 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003502 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003503 }
3504 }
3505 }
3506
3507 return true;
3508}
3509
Austin Kinross6ee1e782015-05-29 17:05:37 -07003510bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3511{
Jamie Madill007530e2017-12-28 14:27:04 -05003512 if (!context->getExtensions().debugMarker)
3513 {
3514 // The debug marker calls should not set error state
3515 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003516 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003517 return false;
3518 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003519
Jamie Madill007530e2017-12-28 14:27:04 -05003520 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003521 if (length < 0)
3522 {
3523 return false;
3524 }
3525
3526 if (marker == nullptr)
3527 {
3528 return false;
3529 }
3530
3531 return true;
3532}
3533
3534bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3535{
Jamie Madill007530e2017-12-28 14:27:04 -05003536 if (!context->getExtensions().debugMarker)
3537 {
3538 // The debug marker calls should not set error state
3539 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003540 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003541 return false;
3542 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003543
Jamie Madill007530e2017-12-28 14:27:04 -05003544 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003545 if (length < 0)
3546 {
3547 return false;
3548 }
3549
3550 if (length > 0 && marker == nullptr)
3551 {
3552 return false;
3553 }
3554
3555 return true;
3556}
3557
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003558bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003559{
Geoff Langa8406172015-07-21 16:53:39 -04003560 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3561 {
Jamie Madille0472f32018-11-27 16:32:45 -05003562 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003563 return false;
3564 }
3565
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003566 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003567 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003568 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003569 if (!context->getExtensions().eglImage)
3570 {
Jamie Madill610640f2018-11-21 17:28:41 -05003571 context->validationError(GL_INVALID_ENUM,
3572 "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003573 }
3574 break;
3575
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003576 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003577 if (!context->getExtensions().eglImageExternal)
3578 {
Jamie Madill610640f2018-11-21 17:28:41 -05003579 context->validationError(GL_INVALID_ENUM,
3580 "GL_TEXTURE_EXTERNAL_OES texture target "
3581 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003582 }
Geoff Langa8406172015-07-21 16:53:39 -04003583 break;
3584
3585 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003586 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003587 return false;
3588 }
3589
Rafael Cintron05a449a2018-06-20 18:08:04 -07003590 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003591
Jamie Madill61e16b42017-06-19 11:13:23 -04003592 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003593 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003594 {
Jamie Madill610640f2018-11-21 17:28:41 -05003595 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003596 return false;
3597 }
3598
Jamie Madill007530e2017-12-28 14:27:04 -05003599 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003600 {
Jamie Madill610640f2018-11-21 17:28:41 -05003601 context->validationError(GL_INVALID_OPERATION,
3602 "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003603 return false;
3604 }
3605
Yuly Novikov2eb54072018-08-22 16:41:26 -04003606 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003607 {
Jamie Madill610640f2018-11-21 17:28:41 -05003608 context->validationError(GL_INVALID_OPERATION,
3609 "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003610 return false;
3611 }
3612
Geoff Langdcab33b2015-07-21 13:03:16 -04003613 return true;
3614}
3615
3616bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003617 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003618 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003619{
Geoff Langa8406172015-07-21 16:53:39 -04003620 if (!context->getExtensions().eglImage)
3621 {
Jamie Madille0472f32018-11-27 16:32:45 -05003622 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003623 return false;
3624 }
3625
3626 switch (target)
3627 {
3628 case GL_RENDERBUFFER:
3629 break;
3630
3631 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003632 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003633 return false;
3634 }
3635
Rafael Cintron05a449a2018-06-20 18:08:04 -07003636 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003637
Jamie Madill61e16b42017-06-19 11:13:23 -04003638 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003639 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003640 {
Jamie Madill610640f2018-11-21 17:28:41 -05003641 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003642 return false;
3643 }
3644
Yuly Novikov2eb54072018-08-22 16:41:26 -04003645 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003646 {
Jamie Madill610640f2018-11-21 17:28:41 -05003647 context->validationError(GL_INVALID_OPERATION,
3648 "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003649 return false;
3650 }
3651
Geoff Langdcab33b2015-07-21 13:03:16 -04003652 return true;
3653}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003654
3655bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3656{
Geoff Lang36167ab2015-12-07 10:27:14 -05003657 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003658 {
3659 // The default VAO should always exist
3660 ASSERT(array != 0);
Jamie Madille0472f32018-11-27 16:32:45 -05003661 context->validationError(GL_INVALID_OPERATION, kInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003662 return false;
3663 }
3664
3665 return true;
3666}
3667
Geoff Langc5629752015-12-07 16:29:04 -05003668bool ValidateProgramBinaryBase(Context *context,
3669 GLuint program,
3670 GLenum binaryFormat,
3671 const void *binary,
3672 GLint length)
3673{
3674 Program *programObject = GetValidProgram(context, program);
3675 if (programObject == nullptr)
3676 {
3677 return false;
3678 }
3679
3680 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3681 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3682 programBinaryFormats.end())
3683 {
Jamie Madill610640f2018-11-21 17:28:41 -05003684 context->validationError(GL_INVALID_ENUM, "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003685 return false;
3686 }
3687
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003688 if (context->hasActiveTransformFeedback(program))
3689 {
3690 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05003691 context->validationError(GL_INVALID_OPERATION,
3692 "Cannot change program binary while program "
3693 "is associated with an active transform "
3694 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003695 return false;
3696 }
3697
Geoff Langc5629752015-12-07 16:29:04 -05003698 return true;
3699}
3700
3701bool ValidateGetProgramBinaryBase(Context *context,
3702 GLuint program,
3703 GLsizei bufSize,
3704 GLsizei *length,
3705 GLenum *binaryFormat,
3706 void *binary)
3707{
3708 Program *programObject = GetValidProgram(context, program);
3709 if (programObject == nullptr)
3710 {
3711 return false;
3712 }
3713
3714 if (!programObject->isLinked())
3715 {
Jamie Madille0472f32018-11-27 16:32:45 -05003716 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003717 return false;
3718 }
3719
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003720 if (context->getCaps().programBinaryFormats.empty())
3721 {
Jamie Madill610640f2018-11-21 17:28:41 -05003722 context->validationError(GL_INVALID_OPERATION, "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003723 return false;
3724 }
3725
Geoff Langc5629752015-12-07 16:29:04 -05003726 return true;
3727}
Jamie Madillc29968b2016-01-20 11:17:23 -05003728
Jamie Madill5b772312018-03-08 20:28:32 -05003729bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003730{
3731 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003732 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003733 {
Jamie Madille0472f32018-11-27 16:32:45 -05003734 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003735 return false;
3736 }
3737 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3738 {
Jamie Madille0472f32018-11-27 16:32:45 -05003739 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003740 return false;
3741 }
3742
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003743 ASSERT(context->getGLState().getDrawFramebuffer());
3744 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003745 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3746
3747 // This should come first before the check for the default frame buffer
3748 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3749 // rather than INVALID_OPERATION
3750 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3751 {
3752 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3753
3754 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003755 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3756 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003757 {
3758 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003759 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3760 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3761 // 3.1 is still a bit ambiguous about the error, but future specs are
3762 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madill610640f2018-11-21 17:28:41 -05003763 context->validationError(GL_INVALID_ENUM, "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003764 return false;
3765 }
3766 else if (bufs[colorAttachment] >= maxColorAttachment)
3767 {
Jamie Madill610640f2018-11-21 17:28:41 -05003768 context->validationError(GL_INVALID_OPERATION,
3769 "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003770 return false;
3771 }
3772 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3773 frameBufferId != 0)
3774 {
3775 // INVALID_OPERATION-GL is bound to buffer and ith argument
3776 // is not COLOR_ATTACHMENTi or NONE
Jamie Madill610640f2018-11-21 17:28:41 -05003777 context->validationError(GL_INVALID_OPERATION,
3778 "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003779 return false;
3780 }
3781 }
3782
3783 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3784 // and n is not 1 or bufs is bound to value other than BACK and NONE
3785 if (frameBufferId == 0)
3786 {
3787 if (n != 1)
3788 {
Jamie Madill610640f2018-11-21 17:28:41 -05003789 context->validationError(GL_INVALID_OPERATION,
3790 "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003791 return false;
3792 }
3793
3794 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3795 {
Jamie Madill610640f2018-11-21 17:28:41 -05003796 context->validationError(
3797 GL_INVALID_OPERATION,
3798 "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003799 return false;
3800 }
3801 }
3802
3803 return true;
3804}
3805
Geoff Lang496c02d2016-10-20 11:38:11 -07003806bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003807 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003808 GLenum pname,
3809 GLsizei *length,
3810 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003811{
Geoff Lang496c02d2016-10-20 11:38:11 -07003812 if (length)
3813 {
3814 *length = 0;
3815 }
3816
3817 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3818 {
Jamie Madill610640f2018-11-21 17:28:41 -05003819 context->validationError(
3820 GL_INVALID_OPERATION,
3821 "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003822 return false;
3823 }
3824
Corentin Walleze4477002017-12-01 14:39:58 -05003825 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003826 {
Jamie Madill610640f2018-11-21 17:28:41 -05003827 context->validationError(GL_INVALID_ENUM, "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003828 return false;
3829 }
3830
Geoff Lang496c02d2016-10-20 11:38:11 -07003831 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003832 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003833 case GL_BUFFER_MAP_POINTER:
3834 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003835
Geoff Lang496c02d2016-10-20 11:38:11 -07003836 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003837 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003838 return false;
3839 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003840
3841 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3842 // target bound to zero generate an INVALID_OPERATION error."
3843 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003844 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003845 {
Jamie Madill610640f2018-11-21 17:28:41 -05003846 context->validationError(GL_INVALID_OPERATION,
3847 "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003848 return false;
3849 }
3850
Geoff Lang496c02d2016-10-20 11:38:11 -07003851 if (length)
3852 {
3853 *length = 1;
3854 }
3855
Olli Etuaho4f667482016-03-30 15:56:35 +03003856 return true;
3857}
3858
Corentin Wallez336129f2017-10-17 15:55:40 -04003859bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003860{
Corentin Walleze4477002017-12-01 14:39:58 -05003861 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003862 {
Jamie Madille0472f32018-11-27 16:32:45 -05003863 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003864 return false;
3865 }
3866
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003867 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003868
3869 if (buffer == nullptr || !buffer->isMapped())
3870 {
Jamie Madill610640f2018-11-21 17:28:41 -05003871 context->validationError(GL_INVALID_OPERATION, "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003872 return false;
3873 }
3874
3875 return true;
3876}
3877
3878bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003879 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003880 GLintptr offset,
3881 GLsizeiptr length,
3882 GLbitfield access)
3883{
Corentin Walleze4477002017-12-01 14:39:58 -05003884 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003885 {
Jamie Madille0472f32018-11-27 16:32:45 -05003886 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003887 return false;
3888 }
3889
Brandon Jones6cad5662017-06-14 13:25:13 -07003890 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003891 {
Jamie Madille0472f32018-11-27 16:32:45 -05003892 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003893 return false;
3894 }
3895
3896 if (length < 0)
3897 {
Jamie Madille0472f32018-11-27 16:32:45 -05003898 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003899 return false;
3900 }
3901
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003902 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003903
3904 if (!buffer)
3905 {
Jamie Madill610640f2018-11-21 17:28:41 -05003906 context->validationError(GL_INVALID_OPERATION, "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003907 return false;
3908 }
3909
3910 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003911 CheckedNumeric<size_t> checkedOffset(offset);
3912 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003913
Jamie Madille2e406c2016-06-02 13:04:10 -04003914 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003915 {
Jamie Madill610640f2018-11-21 17:28:41 -05003916 context->validationError(GL_INVALID_VALUE,
3917 "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003918 return false;
3919 }
3920
3921 // Check for invalid bits in the mask
3922 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3923 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3924 GL_MAP_UNSYNCHRONIZED_BIT;
3925
3926 if (access & ~(allAccessBits))
3927 {
Jamie Madill610640f2018-11-21 17:28:41 -05003928 context->validationError(GL_INVALID_VALUE, "Invalid access bits");
Olli Etuaho4f667482016-03-30 15:56:35 +03003929 return false;
3930 }
3931
3932 if (length == 0)
3933 {
Jamie Madill610640f2018-11-21 17:28:41 -05003934 context->validationError(GL_INVALID_OPERATION, "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003935 return false;
3936 }
3937
3938 if (buffer->isMapped())
3939 {
Jamie Madill610640f2018-11-21 17:28:41 -05003940 context->validationError(GL_INVALID_OPERATION, "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003941 return false;
3942 }
3943
3944 // Check for invalid bit combinations
3945 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3946 {
Jamie Madill610640f2018-11-21 17:28:41 -05003947 context->validationError(GL_INVALID_OPERATION,
3948 "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003949 return false;
3950 }
3951
3952 GLbitfield writeOnlyBits =
3953 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3954
3955 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3956 {
Jamie Madill610640f2018-11-21 17:28:41 -05003957 context->validationError(GL_INVALID_OPERATION,
3958 "Invalid access bits when mapping buffer for reading");
Olli Etuaho4f667482016-03-30 15:56:35 +03003959 return false;
3960 }
3961
3962 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3963 {
Jamie Madill610640f2018-11-21 17:28:41 -05003964 context->validationError(
3965 GL_INVALID_OPERATION,
3966 "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003967 return false;
3968 }
Geoff Lang79f71042017-08-14 16:43:43 -04003969
3970 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003971}
3972
3973bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003974 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003975 GLintptr offset,
3976 GLsizeiptr length)
3977{
Brandon Jones6cad5662017-06-14 13:25:13 -07003978 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003979 {
Jamie Madille0472f32018-11-27 16:32:45 -05003980 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003981 return false;
3982 }
3983
3984 if (length < 0)
3985 {
Jamie Madille0472f32018-11-27 16:32:45 -05003986 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003987 return false;
3988 }
3989
Corentin Walleze4477002017-12-01 14:39:58 -05003990 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003991 {
Jamie Madille0472f32018-11-27 16:32:45 -05003992 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003993 return false;
3994 }
3995
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003996 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003997
3998 if (buffer == nullptr)
3999 {
Jamie Madill610640f2018-11-21 17:28:41 -05004000 context->validationError(GL_INVALID_OPERATION, "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004001 return false;
4002 }
4003
4004 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
4005 {
Jamie Madill610640f2018-11-21 17:28:41 -05004006 context->validationError(GL_INVALID_OPERATION,
4007 "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004008 return false;
4009 }
4010
4011 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04004012 CheckedNumeric<size_t> checkedOffset(offset);
4013 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03004014
Jamie Madille2e406c2016-06-02 13:04:10 -04004015 if (!checkedSize.IsValid() ||
4016 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03004017 {
Jamie Madill610640f2018-11-21 17:28:41 -05004018 context->validationError(GL_INVALID_VALUE,
4019 "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004020 return false;
4021 }
4022
4023 return true;
4024}
4025
Olli Etuaho41997e72016-03-10 13:38:39 +02004026bool ValidateGenOrDelete(Context *context, GLint n)
4027{
4028 if (n < 0)
4029 {
Jamie Madille0472f32018-11-27 16:32:45 -05004030 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004031 return false;
4032 }
4033 return true;
4034}
4035
Jamie Madill5b772312018-03-08 20:28:32 -05004036bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004037{
4038 if (!context->getExtensions().robustClientMemory)
4039 {
Jamie Madill610640f2018-11-21 17:28:41 -05004040 context->validationError(GL_INVALID_OPERATION,
4041 "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004042 return false;
4043 }
4044
4045 if (bufSize < 0)
4046 {
Jamie Madille0472f32018-11-27 16:32:45 -05004047 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004048 return false;
4049 }
4050
4051 return true;
4052}
4053
Jamie Madill5b772312018-03-08 20:28:32 -05004054bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004055{
4056 if (bufSize < numParams)
4057 {
Jamie Madill610640f2018-11-21 17:28:41 -05004058 context->validationError(GL_INVALID_OPERATION,
4059 "More parameters are required than were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004060 return false;
4061 }
4062
4063 return true;
4064}
4065
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004066bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004067 GLenum target,
4068 GLenum attachment,
4069 GLenum pname,
4070 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004071{
Geoff Lange8afa902017-09-27 15:00:43 -04004072 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004073 {
Jamie Madille0472f32018-11-27 16:32:45 -05004074 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004075 return false;
4076 }
4077
4078 int clientVersion = context->getClientMajorVersion();
4079
4080 switch (pname)
4081 {
4082 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4083 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4084 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4085 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4086 break;
4087
Martin Radeve5285d22017-07-14 16:23:53 +03004088 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4089 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4090 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4091 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4092 if (clientVersion < 3 || !context->getExtensions().multiview)
4093 {
Jamie Madille0472f32018-11-27 16:32:45 -05004094 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03004095 return false;
4096 }
4097 break;
4098
Geoff Langff5b2d52016-09-07 11:32:23 -04004099 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4100 if (clientVersion < 3 && !context->getExtensions().sRGB)
4101 {
Jamie Madille0472f32018-11-27 16:32:45 -05004102 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004103 return false;
4104 }
4105 break;
4106
4107 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4108 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4109 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4110 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4111 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4112 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4113 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4114 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4115 if (clientVersion < 3)
4116 {
Jamie Madille0472f32018-11-27 16:32:45 -05004117 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004118 return false;
4119 }
4120 break;
4121
Jiawei Shaoa8802472018-05-28 11:17:47 +08004122 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4123 if (!context->getExtensions().geometryShader)
4124 {
Jamie Madille0472f32018-11-27 16:32:45 -05004125 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08004126 return false;
4127 }
4128 break;
4129
Geoff Langff5b2d52016-09-07 11:32:23 -04004130 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004131 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04004132 return false;
4133 }
4134
4135 // Determine if the attachment is a valid enum
4136 switch (attachment)
4137 {
4138 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004139 case GL_DEPTH:
4140 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004141 if (clientVersion < 3)
4142 {
Jamie Madille0472f32018-11-27 16:32:45 -05004143 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004144 return false;
4145 }
4146 break;
4147
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004148 case GL_DEPTH_STENCIL_ATTACHMENT:
4149 if (clientVersion < 3 && !context->isWebGL1())
4150 {
Jamie Madille0472f32018-11-27 16:32:45 -05004151 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004152 return false;
4153 }
4154 break;
4155
Geoff Langfa125c92017-10-24 13:01:46 -04004156 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004157 case GL_DEPTH_ATTACHMENT:
4158 case GL_STENCIL_ATTACHMENT:
4159 break;
4160
4161 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004162 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4163 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004164 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4165 {
Jamie Madille0472f32018-11-27 16:32:45 -05004166 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004167 return false;
4168 }
4169 break;
4170 }
4171
4172 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4173 ASSERT(framebuffer);
4174
4175 if (framebuffer->id() == 0)
4176 {
4177 if (clientVersion < 3)
4178 {
Jamie Madille0472f32018-11-27 16:32:45 -05004179 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004180 return false;
4181 }
4182
4183 switch (attachment)
4184 {
4185 case GL_BACK:
4186 case GL_DEPTH:
4187 case GL_STENCIL:
4188 break;
4189
4190 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004191 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004192 return false;
4193 }
4194 }
4195 else
4196 {
4197 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4198 {
4199 // Valid attachment query
4200 }
4201 else
4202 {
4203 switch (attachment)
4204 {
4205 case GL_DEPTH_ATTACHMENT:
4206 case GL_STENCIL_ATTACHMENT:
4207 break;
4208
4209 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004210 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004211 {
Jamie Madille0472f32018-11-27 16:32:45 -05004212 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004213 return false;
4214 }
4215 break;
4216
4217 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004218 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004219 return false;
4220 }
4221 }
4222 }
4223
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004224 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004225 if (attachmentObject)
4226 {
4227 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4228 attachmentObject->type() == GL_TEXTURE ||
4229 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4230
4231 switch (pname)
4232 {
4233 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4234 if (attachmentObject->type() != GL_RENDERBUFFER &&
4235 attachmentObject->type() != GL_TEXTURE)
4236 {
Jamie Madille0472f32018-11-27 16:32:45 -05004237 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004238 return false;
4239 }
4240 break;
4241
4242 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4243 if (attachmentObject->type() != GL_TEXTURE)
4244 {
Jamie Madille0472f32018-11-27 16:32:45 -05004245 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004246 return false;
4247 }
4248 break;
4249
4250 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4251 if (attachmentObject->type() != GL_TEXTURE)
4252 {
Jamie Madille0472f32018-11-27 16:32:45 -05004253 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004254 return false;
4255 }
4256 break;
4257
4258 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4259 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4260 {
Jamie Madille0472f32018-11-27 16:32:45 -05004261 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004262 return false;
4263 }
4264 break;
4265
4266 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4267 if (attachmentObject->type() != GL_TEXTURE)
4268 {
Jamie Madille0472f32018-11-27 16:32:45 -05004269 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004270 return false;
4271 }
4272 break;
4273
4274 default:
4275 break;
4276 }
4277 }
4278 else
4279 {
4280 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4281 // is NONE, then querying any other pname will generate INVALID_ENUM.
4282
4283 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4284 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4285 // INVALID_OPERATION for all other pnames
4286
4287 switch (pname)
4288 {
4289 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4290 break;
4291
4292 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4293 if (clientVersion < 3)
4294 {
Jamie Madill610640f2018-11-21 17:28:41 -05004295 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004296 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004297 return false;
4298 }
4299 break;
4300
4301 default:
4302 if (clientVersion < 3)
4303 {
Jamie Madill610640f2018-11-21 17:28:41 -05004304 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004305 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004306 return false;
4307 }
4308 else
4309 {
Jamie Madill610640f2018-11-21 17:28:41 -05004310 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05004311 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004312 return false;
4313 }
4314 }
4315 }
4316
Martin Radeve5285d22017-07-14 16:23:53 +03004317 if (numParams)
4318 {
4319 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4320 {
4321 // Only when the viewport offsets are queried we can have a varying number of output
4322 // parameters.
4323 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4324 *numParams = numViews * 2;
4325 }
4326 else
4327 {
4328 // For all other queries we can have only one output parameter.
4329 *numParams = 1;
4330 }
4331 }
4332
Geoff Langff5b2d52016-09-07 11:32:23 -04004333 return true;
4334}
4335
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004336bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004337 GLenum target,
4338 GLenum attachment,
4339 GLenum pname,
4340 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004341 GLsizei *length,
4342 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004343{
4344 if (!ValidateRobustEntryPoint(context, bufSize))
4345 {
4346 return false;
4347 }
4348
Brandon Jonesd1049182018-03-28 10:02:20 -07004349 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004350 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004351 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004352 {
4353 return false;
4354 }
4355
Brandon Jonesd1049182018-03-28 10:02:20 -07004356 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004357 {
4358 return false;
4359 }
4360
Brandon Jonesd1049182018-03-28 10:02:20 -07004361 SetRobustLengthParam(length, numParams);
4362
Geoff Langff5b2d52016-09-07 11:32:23 -04004363 return true;
4364}
4365
Jamie Madill5b772312018-03-08 20:28:32 -05004366bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004367 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004368 GLenum pname,
4369 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004370 GLsizei *length,
4371 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004372{
4373 if (!ValidateRobustEntryPoint(context, bufSize))
4374 {
4375 return false;
4376 }
4377
Brandon Jonesd1049182018-03-28 10:02:20 -07004378 GLsizei numParams = 0;
4379
4380 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004381 {
4382 return false;
4383 }
4384
Brandon Jonesd1049182018-03-28 10:02:20 -07004385 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004386 {
4387 return false;
4388 }
4389
Brandon Jonesd1049182018-03-28 10:02:20 -07004390 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004391 return true;
4392}
4393
Jamie Madill5b772312018-03-08 20:28:32 -05004394bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004395 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004396 GLenum pname,
4397 GLsizei bufSize,
4398 GLsizei *length,
4399 GLint64 *params)
4400{
Brandon Jonesd1049182018-03-28 10:02:20 -07004401 GLsizei numParams = 0;
4402
Geoff Langebebe1c2016-10-14 12:01:31 -04004403 if (!ValidateRobustEntryPoint(context, bufSize))
4404 {
4405 return false;
4406 }
4407
Brandon Jonesd1049182018-03-28 10:02:20 -07004408 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004409 {
4410 return false;
4411 }
4412
Brandon Jonesd1049182018-03-28 10:02:20 -07004413 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004414 {
4415 return false;
4416 }
4417
Brandon Jonesd1049182018-03-28 10:02:20 -07004418 SetRobustLengthParam(length, numParams);
4419
Geoff Langff5b2d52016-09-07 11:32:23 -04004420 return true;
4421}
4422
Jamie Madill5b772312018-03-08 20:28:32 -05004423bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004424{
4425 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004426 if (numParams)
4427 {
4428 *numParams = 1;
4429 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004430
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004431 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4432 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4433 ? GetValidProgramNoResolve(context, program)
4434 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004435 if (!programObject)
4436 {
4437 return false;
4438 }
4439
4440 switch (pname)
4441 {
4442 case GL_DELETE_STATUS:
4443 case GL_LINK_STATUS:
4444 case GL_VALIDATE_STATUS:
4445 case GL_INFO_LOG_LENGTH:
4446 case GL_ATTACHED_SHADERS:
4447 case GL_ACTIVE_ATTRIBUTES:
4448 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4449 case GL_ACTIVE_UNIFORMS:
4450 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4451 break;
4452
4453 case GL_PROGRAM_BINARY_LENGTH:
4454 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4455 {
Jamie Madill610640f2018-11-21 17:28:41 -05004456 context->validationError(GL_INVALID_ENUM,
4457 "Querying GL_PROGRAM_BINARY_LENGTH "
4458 "requires GL_OES_get_program_binary or "
4459 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004460 return false;
4461 }
4462 break;
4463
4464 case GL_ACTIVE_UNIFORM_BLOCKS:
4465 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4466 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4467 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4468 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4469 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4470 if (context->getClientMajorVersion() < 3)
4471 {
Jamie Madille0472f32018-11-27 16:32:45 -05004472 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004473 return false;
4474 }
4475 break;
4476
Yunchao He61afff12017-03-14 15:34:03 +08004477 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004478 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004479 if (context->getClientVersion() < Version(3, 1))
4480 {
Jamie Madille0472f32018-11-27 16:32:45 -05004481 context->validationError(GL_INVALID_ENUM, kES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004482 return false;
4483 }
4484 break;
4485
Jiawei Shao6ae51612018-02-23 14:03:25 +08004486 case GL_COMPUTE_WORK_GROUP_SIZE:
4487 if (context->getClientVersion() < Version(3, 1))
4488 {
Jamie Madille0472f32018-11-27 16:32:45 -05004489 context->validationError(GL_INVALID_ENUM, kES31Required);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004490 return false;
4491 }
4492
4493 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4494 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4495 // program which has not been linked successfully, or which does not contain objects to
4496 // form a compute shader.
4497 if (!programObject->isLinked())
4498 {
Jamie Madille0472f32018-11-27 16:32:45 -05004499 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004500 return false;
4501 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004502 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004503 {
Jamie Madille0472f32018-11-27 16:32:45 -05004504 context->validationError(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004505 return false;
4506 }
4507 break;
4508
Jiawei Shao447bfac2018-03-14 14:23:40 +08004509 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4510 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4511 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4512 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4513 if (!context->getExtensions().geometryShader)
4514 {
Jamie Madille0472f32018-11-27 16:32:45 -05004515 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004516 return false;
4517 }
4518
4519 // [EXT_geometry_shader] Chapter 7.12
4520 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4521 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4522 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4523 // successfully, or which does not contain objects to form a geometry shader.
4524 if (!programObject->isLinked())
4525 {
Jamie Madille0472f32018-11-27 16:32:45 -05004526 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004527 return false;
4528 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004529 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004530 {
Jamie Madille0472f32018-11-27 16:32:45 -05004531 context->validationError(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004532 return false;
4533 }
4534 break;
4535
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004536 case GL_COMPLETION_STATUS_KHR:
4537 if (!context->getExtensions().parallelShaderCompile)
4538 {
Jamie Madille0472f32018-11-27 16:32:45 -05004539 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004540 return false;
4541 }
4542 break;
4543
Geoff Langff5b2d52016-09-07 11:32:23 -04004544 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004545 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004546 return false;
4547 }
4548
4549 return true;
4550}
4551
4552bool ValidateGetProgramivRobustANGLE(Context *context,
4553 GLuint program,
4554 GLenum pname,
4555 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004556 GLsizei *length,
4557 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004558{
4559 if (!ValidateRobustEntryPoint(context, bufSize))
4560 {
4561 return false;
4562 }
4563
Brandon Jonesd1049182018-03-28 10:02:20 -07004564 GLsizei numParams = 0;
4565
4566 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004567 {
4568 return false;
4569 }
4570
Brandon Jonesd1049182018-03-28 10:02:20 -07004571 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004572 {
4573 return false;
4574 }
4575
Brandon Jonesd1049182018-03-28 10:02:20 -07004576 SetRobustLengthParam(length, numParams);
4577
Geoff Langff5b2d52016-09-07 11:32:23 -04004578 return true;
4579}
4580
Geoff Lang740d9022016-10-07 11:20:52 -04004581bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4582 GLenum target,
4583 GLenum pname,
4584 GLsizei bufSize,
4585 GLsizei *length,
4586 GLint *params)
4587{
4588 if (!ValidateRobustEntryPoint(context, bufSize))
4589 {
4590 return false;
4591 }
4592
Brandon Jonesd1049182018-03-28 10:02:20 -07004593 GLsizei numParams = 0;
4594
4595 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004596 {
4597 return false;
4598 }
4599
Brandon Jonesd1049182018-03-28 10:02:20 -07004600 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004601 {
4602 return false;
4603 }
4604
Brandon Jonesd1049182018-03-28 10:02:20 -07004605 SetRobustLengthParam(length, numParams);
4606
Geoff Lang740d9022016-10-07 11:20:52 -04004607 return true;
4608}
4609
Geoff Langd7d0ed32016-10-07 11:33:51 -04004610bool ValidateGetShaderivRobustANGLE(Context *context,
4611 GLuint shader,
4612 GLenum pname,
4613 GLsizei bufSize,
4614 GLsizei *length,
4615 GLint *params)
4616{
4617 if (!ValidateRobustEntryPoint(context, bufSize))
4618 {
4619 return false;
4620 }
4621
Brandon Jonesd1049182018-03-28 10:02:20 -07004622 GLsizei numParams = 0;
4623
4624 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004625 {
4626 return false;
4627 }
4628
Brandon Jonesd1049182018-03-28 10:02:20 -07004629 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004630 {
4631 return false;
4632 }
4633
Brandon Jonesd1049182018-03-28 10:02:20 -07004634 SetRobustLengthParam(length, numParams);
4635
Geoff Langd7d0ed32016-10-07 11:33:51 -04004636 return true;
4637}
4638
Geoff Langc1984ed2016-10-07 12:41:00 -04004639bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004640 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004641 GLenum pname,
4642 GLsizei bufSize,
4643 GLsizei *length,
4644 GLfloat *params)
4645{
4646 if (!ValidateRobustEntryPoint(context, bufSize))
4647 {
4648 return false;
4649 }
4650
Brandon Jonesd1049182018-03-28 10:02:20 -07004651 GLsizei numParams = 0;
4652
4653 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004654 {
4655 return false;
4656 }
4657
Brandon Jonesd1049182018-03-28 10:02:20 -07004658 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004659 {
4660 return false;
4661 }
4662
Brandon Jonesd1049182018-03-28 10:02:20 -07004663 SetRobustLengthParam(length, numParams);
4664
Geoff Langc1984ed2016-10-07 12:41:00 -04004665 return true;
4666}
4667
Geoff Langc1984ed2016-10-07 12:41:00 -04004668bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004669 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004670 GLenum pname,
4671 GLsizei bufSize,
4672 GLsizei *length,
4673 GLint *params)
4674{
Brandon Jonesd1049182018-03-28 10:02:20 -07004675
Geoff Langc1984ed2016-10-07 12:41:00 -04004676 if (!ValidateRobustEntryPoint(context, bufSize))
4677 {
4678 return false;
4679 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004680 GLsizei numParams = 0;
4681 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004682 {
4683 return false;
4684 }
4685
Brandon Jonesd1049182018-03-28 10:02:20 -07004686 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004687 {
4688 return false;
4689 }
4690
Brandon Jonesd1049182018-03-28 10:02:20 -07004691 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004692 return true;
4693}
4694
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004695bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4696 TextureType target,
4697 GLenum pname,
4698 GLsizei bufSize,
4699 GLsizei *length,
4700 GLint *params)
4701{
4702 UNIMPLEMENTED();
4703 return false;
4704}
4705
4706bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4707 TextureType target,
4708 GLenum pname,
4709 GLsizei bufSize,
4710 GLsizei *length,
4711 GLuint *params)
4712{
4713 UNIMPLEMENTED();
4714 return false;
4715}
4716
Geoff Langc1984ed2016-10-07 12:41:00 -04004717bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004718 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004719 GLenum pname,
4720 GLsizei bufSize,
4721 const GLfloat *params)
4722{
4723 if (!ValidateRobustEntryPoint(context, bufSize))
4724 {
4725 return false;
4726 }
4727
Till Rathmannb8543632018-10-02 19:46:14 +02004728 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004729}
4730
Geoff Langc1984ed2016-10-07 12:41:00 -04004731bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004732 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004733 GLenum pname,
4734 GLsizei bufSize,
4735 const GLint *params)
4736{
4737 if (!ValidateRobustEntryPoint(context, bufSize))
4738 {
4739 return false;
4740 }
4741
Till Rathmannb8543632018-10-02 19:46:14 +02004742 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004743}
4744
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004745bool ValidateTexParameterIivRobustANGLE(Context *context,
4746 TextureType target,
4747 GLenum pname,
4748 GLsizei bufSize,
4749 const GLint *params)
4750{
4751 UNIMPLEMENTED();
4752 return false;
4753}
4754
4755bool ValidateTexParameterIuivRobustANGLE(Context *context,
4756 TextureType target,
4757 GLenum pname,
4758 GLsizei bufSize,
4759 const GLuint *params)
4760{
4761 UNIMPLEMENTED();
4762 return false;
4763}
4764
Geoff Langc1984ed2016-10-07 12:41:00 -04004765bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4766 GLuint sampler,
4767 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004768 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004769 GLsizei *length,
4770 GLfloat *params)
4771{
4772 if (!ValidateRobustEntryPoint(context, bufSize))
4773 {
4774 return false;
4775 }
4776
Brandon Jonesd1049182018-03-28 10:02:20 -07004777 GLsizei numParams = 0;
4778
4779 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004780 {
4781 return false;
4782 }
4783
Brandon Jonesd1049182018-03-28 10:02:20 -07004784 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004785 {
4786 return false;
4787 }
4788
Brandon Jonesd1049182018-03-28 10:02:20 -07004789 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004790 return true;
4791}
4792
Geoff Langc1984ed2016-10-07 12:41:00 -04004793bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4794 GLuint sampler,
4795 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004796 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004797 GLsizei *length,
4798 GLint *params)
4799{
4800 if (!ValidateRobustEntryPoint(context, bufSize))
4801 {
4802 return false;
4803 }
4804
Brandon Jonesd1049182018-03-28 10:02:20 -07004805 GLsizei numParams = 0;
4806
4807 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004808 {
4809 return false;
4810 }
4811
Brandon Jonesd1049182018-03-28 10:02:20 -07004812 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004813 {
4814 return false;
4815 }
4816
Brandon Jonesd1049182018-03-28 10:02:20 -07004817 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004818 return true;
4819}
4820
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004821bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4822 GLuint sampler,
4823 GLenum pname,
4824 GLsizei bufSize,
4825 GLsizei *length,
4826 GLint *params)
4827{
4828 UNIMPLEMENTED();
4829 return false;
4830}
4831
4832bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4833 GLuint sampler,
4834 GLenum pname,
4835 GLsizei bufSize,
4836 GLsizei *length,
4837 GLuint *params)
4838{
4839 UNIMPLEMENTED();
4840 return false;
4841}
4842
Geoff Langc1984ed2016-10-07 12:41:00 -04004843bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4844 GLuint sampler,
4845 GLenum pname,
4846 GLsizei bufSize,
4847 const GLfloat *params)
4848{
4849 if (!ValidateRobustEntryPoint(context, bufSize))
4850 {
4851 return false;
4852 }
4853
Till Rathmannb8543632018-10-02 19:46:14 +02004854 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004855}
4856
Geoff Langc1984ed2016-10-07 12:41:00 -04004857bool ValidateSamplerParameterivRobustANGLE(Context *context,
4858 GLuint sampler,
4859 GLenum pname,
4860 GLsizei bufSize,
4861 const GLint *params)
4862{
4863 if (!ValidateRobustEntryPoint(context, bufSize))
4864 {
4865 return false;
4866 }
4867
Till Rathmannb8543632018-10-02 19:46:14 +02004868 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004869}
4870
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004871bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4872 GLuint sampler,
4873 GLenum pname,
4874 GLsizei bufSize,
4875 const GLint *param)
4876{
4877 UNIMPLEMENTED();
4878 return false;
4879}
4880
4881bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4882 GLuint sampler,
4883 GLenum pname,
4884 GLsizei bufSize,
4885 const GLuint *param)
4886{
4887 UNIMPLEMENTED();
4888 return false;
4889}
4890
Geoff Lang0b031062016-10-13 14:30:04 -04004891bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4892 GLuint index,
4893 GLenum pname,
4894 GLsizei bufSize,
4895 GLsizei *length,
4896 GLfloat *params)
4897{
4898 if (!ValidateRobustEntryPoint(context, bufSize))
4899 {
4900 return false;
4901 }
4902
Brandon Jonesd1049182018-03-28 10:02:20 -07004903 GLsizei writeLength = 0;
4904
4905 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004906 {
4907 return false;
4908 }
4909
Brandon Jonesd1049182018-03-28 10:02:20 -07004910 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004911 {
4912 return false;
4913 }
4914
Brandon Jonesd1049182018-03-28 10:02:20 -07004915 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004916 return true;
4917}
4918
Geoff Lang0b031062016-10-13 14:30:04 -04004919bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4920 GLuint index,
4921 GLenum pname,
4922 GLsizei bufSize,
4923 GLsizei *length,
4924 GLint *params)
4925{
4926 if (!ValidateRobustEntryPoint(context, bufSize))
4927 {
4928 return false;
4929 }
4930
Brandon Jonesd1049182018-03-28 10:02:20 -07004931 GLsizei writeLength = 0;
4932
4933 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004934 {
4935 return false;
4936 }
4937
Brandon Jonesd1049182018-03-28 10:02:20 -07004938 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004939 {
4940 return false;
4941 }
4942
Brandon Jonesd1049182018-03-28 10:02:20 -07004943 SetRobustLengthParam(length, writeLength);
4944
Geoff Lang0b031062016-10-13 14:30:04 -04004945 return true;
4946}
4947
Geoff Lang0b031062016-10-13 14:30:04 -04004948bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4949 GLuint index,
4950 GLenum pname,
4951 GLsizei bufSize,
4952 GLsizei *length,
4953 void **pointer)
4954{
4955 if (!ValidateRobustEntryPoint(context, bufSize))
4956 {
4957 return false;
4958 }
4959
Brandon Jonesd1049182018-03-28 10:02:20 -07004960 GLsizei writeLength = 0;
4961
4962 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004963 {
4964 return false;
4965 }
4966
Brandon Jonesd1049182018-03-28 10:02:20 -07004967 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004968 {
4969 return false;
4970 }
4971
Brandon Jonesd1049182018-03-28 10:02:20 -07004972 SetRobustLengthParam(length, writeLength);
4973
Geoff Lang0b031062016-10-13 14:30:04 -04004974 return true;
4975}
4976
Geoff Lang0b031062016-10-13 14:30:04 -04004977bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4978 GLuint index,
4979 GLenum pname,
4980 GLsizei bufSize,
4981 GLsizei *length,
4982 GLint *params)
4983{
4984 if (!ValidateRobustEntryPoint(context, bufSize))
4985 {
4986 return false;
4987 }
4988
Brandon Jonesd1049182018-03-28 10:02:20 -07004989 GLsizei writeLength = 0;
4990
4991 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004992 {
4993 return false;
4994 }
4995
Brandon Jonesd1049182018-03-28 10:02:20 -07004996 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004997 {
4998 return false;
4999 }
5000
Brandon Jonesd1049182018-03-28 10:02:20 -07005001 SetRobustLengthParam(length, writeLength);
5002
Geoff Lang0b031062016-10-13 14:30:04 -04005003 return true;
5004}
5005
Geoff Lang0b031062016-10-13 14:30:04 -04005006bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
5007 GLuint index,
5008 GLenum pname,
5009 GLsizei bufSize,
5010 GLsizei *length,
5011 GLuint *params)
5012{
5013 if (!ValidateRobustEntryPoint(context, bufSize))
5014 {
5015 return false;
5016 }
5017
Brandon Jonesd1049182018-03-28 10:02:20 -07005018 GLsizei writeLength = 0;
5019
5020 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04005021 {
5022 return false;
5023 }
5024
Brandon Jonesd1049182018-03-28 10:02:20 -07005025 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04005026 {
5027 return false;
5028 }
5029
Brandon Jonesd1049182018-03-28 10:02:20 -07005030 SetRobustLengthParam(length, writeLength);
5031
Geoff Lang0b031062016-10-13 14:30:04 -04005032 return true;
5033}
5034
Geoff Lang6899b872016-10-14 11:30:13 -04005035bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5036 GLuint program,
5037 GLuint uniformBlockIndex,
5038 GLenum pname,
5039 GLsizei bufSize,
5040 GLsizei *length,
5041 GLint *params)
5042{
5043 if (!ValidateRobustEntryPoint(context, bufSize))
5044 {
5045 return false;
5046 }
5047
Brandon Jonesd1049182018-03-28 10:02:20 -07005048 GLsizei writeLength = 0;
5049
5050 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5051 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005052 {
5053 return false;
5054 }
5055
Brandon Jonesd1049182018-03-28 10:02:20 -07005056 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005057 {
5058 return false;
5059 }
5060
Brandon Jonesd1049182018-03-28 10:02:20 -07005061 SetRobustLengthParam(length, writeLength);
5062
Geoff Lang6899b872016-10-14 11:30:13 -04005063 return true;
5064}
5065
Brandon Jones416aaf92018-04-10 08:10:16 -07005066bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005067 GLenum target,
5068 GLenum internalformat,
5069 GLenum pname,
5070 GLsizei bufSize,
5071 GLsizei *length,
5072 GLint *params)
5073{
5074 if (!ValidateRobustEntryPoint(context, bufSize))
5075 {
5076 return false;
5077 }
5078
Brandon Jonesd1049182018-03-28 10:02:20 -07005079 GLsizei numParams = 0;
5080
5081 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5082 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005083 {
5084 return false;
5085 }
5086
Brandon Jonesd1049182018-03-28 10:02:20 -07005087 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005088 {
5089 return false;
5090 }
5091
Brandon Jonesd1049182018-03-28 10:02:20 -07005092 SetRobustLengthParam(length, numParams);
5093
Geoff Lang0a9661f2016-10-20 10:59:20 -07005094 return true;
5095}
5096
Jamie Madill5b772312018-03-08 20:28:32 -05005097bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005098 GLuint attribIndex,
5099 GLint size,
5100 GLenum type,
5101 GLboolean pureInteger)
5102{
5103 const Caps &caps = context->getCaps();
5104 if (attribIndex >= caps.maxVertexAttributes)
5105 {
Jamie Madille0472f32018-11-27 16:32:45 -05005106 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005107 return false;
5108 }
5109
5110 if (size < 1 || size > 4)
5111 {
Jamie Madille0472f32018-11-27 16:32:45 -05005112 context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005113 return false;
Shao80957d92017-02-20 21:25:59 +08005114 }
5115
5116 switch (type)
5117 {
5118 case GL_BYTE:
5119 case GL_UNSIGNED_BYTE:
5120 case GL_SHORT:
5121 case GL_UNSIGNED_SHORT:
5122 break;
5123
5124 case GL_INT:
5125 case GL_UNSIGNED_INT:
5126 if (context->getClientMajorVersion() < 3)
5127 {
Jamie Madill610640f2018-11-21 17:28:41 -05005128 context->validationError(GL_INVALID_ENUM,
5129 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005130 return false;
5131 }
5132 break;
5133
5134 case GL_FIXED:
5135 case GL_FLOAT:
5136 if (pureInteger)
5137 {
Jamie Madille0472f32018-11-27 16:32:45 -05005138 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005139 return false;
5140 }
5141 break;
5142
5143 case GL_HALF_FLOAT:
5144 if (context->getClientMajorVersion() < 3)
5145 {
Jamie Madill610640f2018-11-21 17:28:41 -05005146 context->validationError(GL_INVALID_ENUM,
5147 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005148 return false;
5149 }
5150 if (pureInteger)
5151 {
Jamie Madille0472f32018-11-27 16:32:45 -05005152 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005153 return false;
5154 }
5155 break;
5156
5157 case GL_INT_2_10_10_10_REV:
5158 case GL_UNSIGNED_INT_2_10_10_10_REV:
5159 if (context->getClientMajorVersion() < 3)
5160 {
Jamie Madill610640f2018-11-21 17:28:41 -05005161 context->validationError(GL_INVALID_ENUM,
5162 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005163 return false;
5164 }
5165 if (pureInteger)
5166 {
Jamie Madille0472f32018-11-27 16:32:45 -05005167 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005168 return false;
5169 }
5170 if (size != 4)
5171 {
Jamie Madill610640f2018-11-21 17:28:41 -05005172 context->validationError(GL_INVALID_OPERATION,
5173 "Type is INT_2_10_10_10_REV or "
5174 "UNSIGNED_INT_2_10_10_10_REV and "
5175 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005176 return false;
5177 }
5178 break;
5179
5180 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005181 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08005182 return false;
5183 }
5184
5185 return true;
5186}
5187
Geoff Lang76e65652017-03-27 14:58:02 -04005188// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5189// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5190// specified clear value and the type of a buffer that is being cleared generates an
5191// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005192bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005193 GLint drawbuffer,
5194 const GLenum *validComponentTypes,
5195 size_t validComponentTypeCount)
5196{
5197 const FramebufferAttachment *attachment =
5198 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5199 if (attachment)
5200 {
5201 GLenum componentType = attachment->getFormat().info->componentType;
5202 const GLenum *end = validComponentTypes + validComponentTypeCount;
5203 if (std::find(validComponentTypes, end, componentType) == end)
5204 {
Jamie Madill610640f2018-11-21 17:28:41 -05005205 context->validationError(
5206 GL_INVALID_OPERATION,
5207 "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005208 return false;
5209 }
5210 }
5211
5212 return true;
5213}
5214
Jamie Madill5b772312018-03-08 20:28:32 -05005215bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005216{
5217 if (!ValidateRobustEntryPoint(context, dataSize))
5218 {
5219 return false;
5220 }
5221
Jamie Madill43da7c42018-08-01 11:34:49 -04005222 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005223 if (pixelUnpackBuffer == nullptr)
5224 {
5225 if (dataSize < imageSize)
5226 {
Jamie Madill610640f2018-11-21 17:28:41 -05005227 context->validationError(GL_INVALID_OPERATION, "dataSize is too small");
Corentin Wallezb2931602017-04-11 15:58:57 -04005228 }
5229 }
5230 return true;
5231}
5232
Jamie Madill5b772312018-03-08 20:28:32 -05005233bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005234 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005235 GLenum pname,
5236 bool pointerVersion,
5237 GLsizei *numParams)
5238{
5239 if (numParams)
5240 {
5241 *numParams = 0;
5242 }
5243
Corentin Walleze4477002017-12-01 14:39:58 -05005244 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005245 {
Jamie Madille0472f32018-11-27 16:32:45 -05005246 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005247 return false;
5248 }
5249
5250 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5251 if (!buffer)
5252 {
5253 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05005254 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005255 return false;
5256 }
5257
5258 const Extensions &extensions = context->getExtensions();
5259
5260 switch (pname)
5261 {
5262 case GL_BUFFER_USAGE:
5263 case GL_BUFFER_SIZE:
5264 break;
5265
5266 case GL_BUFFER_ACCESS_OES:
5267 if (!extensions.mapBuffer)
5268 {
Jamie Madill610640f2018-11-21 17:28:41 -05005269 context->validationError(GL_INVALID_ENUM,
5270 "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005271 return false;
5272 }
5273 break;
5274
5275 case GL_BUFFER_MAPPED:
5276 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5277 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5278 !extensions.mapBufferRange)
5279 {
Jamie Madill610640f2018-11-21 17:28:41 -05005280 context->validationError(GL_INVALID_ENUM,
5281 "pname requires OpenGL ES 3.0, "
5282 "GL_OES_mapbuffer or "
5283 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005284 return false;
5285 }
5286 break;
5287
5288 case GL_BUFFER_MAP_POINTER:
5289 if (!pointerVersion)
5290 {
Jamie Madill610640f2018-11-21 17:28:41 -05005291 context->validationError(
5292 GL_INVALID_ENUM,
5293 "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005294 return false;
5295 }
5296 break;
5297
5298 case GL_BUFFER_ACCESS_FLAGS:
5299 case GL_BUFFER_MAP_OFFSET:
5300 case GL_BUFFER_MAP_LENGTH:
5301 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5302 {
Jamie Madill610640f2018-11-21 17:28:41 -05005303 context->validationError(
5304 GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005305 return false;
5306 }
5307 break;
5308
Geoff Lang79b91402018-10-04 15:11:30 -04005309 case GL_MEMORY_SIZE_ANGLE:
5310 if (!context->getExtensions().memorySize)
5311 {
Jamie Madille0472f32018-11-27 16:32:45 -05005312 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005313 return false;
5314 }
5315 break;
5316
Jamie Madillbe849e42017-05-02 15:49:00 -04005317 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005318 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005319 return false;
5320 }
5321
5322 // All buffer parameter queries return one value.
5323 if (numParams)
5324 {
5325 *numParams = 1;
5326 }
5327
5328 return true;
5329}
5330
5331bool ValidateGetRenderbufferParameterivBase(Context *context,
5332 GLenum target,
5333 GLenum pname,
5334 GLsizei *length)
5335{
5336 if (length)
5337 {
5338 *length = 0;
5339 }
5340
5341 if (target != GL_RENDERBUFFER)
5342 {
Jamie Madille0472f32018-11-27 16:32:45 -05005343 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005344 return false;
5345 }
5346
5347 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5348 if (renderbuffer == nullptr)
5349 {
Jamie Madille0472f32018-11-27 16:32:45 -05005350 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005351 return false;
5352 }
5353
5354 switch (pname)
5355 {
5356 case GL_RENDERBUFFER_WIDTH:
5357 case GL_RENDERBUFFER_HEIGHT:
5358 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5359 case GL_RENDERBUFFER_RED_SIZE:
5360 case GL_RENDERBUFFER_GREEN_SIZE:
5361 case GL_RENDERBUFFER_BLUE_SIZE:
5362 case GL_RENDERBUFFER_ALPHA_SIZE:
5363 case GL_RENDERBUFFER_DEPTH_SIZE:
5364 case GL_RENDERBUFFER_STENCIL_SIZE:
5365 break;
5366
5367 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5368 if (!context->getExtensions().framebufferMultisample)
5369 {
Jamie Madille0472f32018-11-27 16:32:45 -05005370 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005371 return false;
5372 }
5373 break;
5374
Geoff Lang79b91402018-10-04 15:11:30 -04005375 case GL_MEMORY_SIZE_ANGLE:
5376 if (!context->getExtensions().memorySize)
5377 {
Jamie Madille0472f32018-11-27 16:32:45 -05005378 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005379 return false;
5380 }
5381 break;
5382
Jamie Madillbe849e42017-05-02 15:49:00 -04005383 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005384 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005385 return false;
5386 }
5387
5388 if (length)
5389 {
5390 *length = 1;
5391 }
5392 return true;
5393}
5394
5395bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5396{
5397 if (length)
5398 {
5399 *length = 0;
5400 }
5401
5402 if (GetValidShader(context, shader) == nullptr)
5403 {
5404 return false;
5405 }
5406
5407 switch (pname)
5408 {
5409 case GL_SHADER_TYPE:
5410 case GL_DELETE_STATUS:
5411 case GL_COMPILE_STATUS:
5412 case GL_INFO_LOG_LENGTH:
5413 case GL_SHADER_SOURCE_LENGTH:
5414 break;
5415
5416 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5417 if (!context->getExtensions().translatedShaderSource)
5418 {
Jamie Madille0472f32018-11-27 16:32:45 -05005419 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005420 return false;
5421 }
5422 break;
5423
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005424 case GL_COMPLETION_STATUS_KHR:
5425 if (!context->getExtensions().parallelShaderCompile)
5426 {
Jamie Madille0472f32018-11-27 16:32:45 -05005427 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005428 return false;
5429 }
5430 break;
5431
Jamie Madillbe849e42017-05-02 15:49:00 -04005432 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005433 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005434 return false;
5435 }
5436
5437 if (length)
5438 {
5439 *length = 1;
5440 }
5441 return true;
5442}
5443
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005444bool ValidateGetTexParameterBase(Context *context,
5445 TextureType target,
5446 GLenum pname,
5447 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005448{
5449 if (length)
5450 {
5451 *length = 0;
5452 }
5453
5454 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5455 {
Jamie Madille0472f32018-11-27 16:32:45 -05005456 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005457 return false;
5458 }
5459
5460 if (context->getTargetTexture(target) == nullptr)
5461 {
5462 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005463 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005464 return false;
5465 }
5466
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005467 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5468 {
Jamie Madille0472f32018-11-27 16:32:45 -05005469 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005470 return false;
5471 }
5472
Jamie Madillbe849e42017-05-02 15:49:00 -04005473 switch (pname)
5474 {
5475 case GL_TEXTURE_MAG_FILTER:
5476 case GL_TEXTURE_MIN_FILTER:
5477 case GL_TEXTURE_WRAP_S:
5478 case GL_TEXTURE_WRAP_T:
5479 break;
5480
5481 case GL_TEXTURE_USAGE_ANGLE:
5482 if (!context->getExtensions().textureUsage)
5483 {
Jamie Madille0472f32018-11-27 16:32:45 -05005484 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005485 return false;
5486 }
5487 break;
5488
5489 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005490 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005491 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005492 return false;
5493 }
5494 break;
5495
5496 case GL_TEXTURE_IMMUTABLE_FORMAT:
5497 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5498 {
Jamie Madille0472f32018-11-27 16:32:45 -05005499 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005500 return false;
5501 }
5502 break;
5503
5504 case GL_TEXTURE_WRAP_R:
5505 case GL_TEXTURE_IMMUTABLE_LEVELS:
5506 case GL_TEXTURE_SWIZZLE_R:
5507 case GL_TEXTURE_SWIZZLE_G:
5508 case GL_TEXTURE_SWIZZLE_B:
5509 case GL_TEXTURE_SWIZZLE_A:
5510 case GL_TEXTURE_BASE_LEVEL:
5511 case GL_TEXTURE_MAX_LEVEL:
5512 case GL_TEXTURE_MIN_LOD:
5513 case GL_TEXTURE_MAX_LOD:
5514 case GL_TEXTURE_COMPARE_MODE:
5515 case GL_TEXTURE_COMPARE_FUNC:
5516 if (context->getClientMajorVersion() < 3)
5517 {
Jamie Madill610640f2018-11-21 17:28:41 -05005518 context->validationError(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005519 return false;
5520 }
5521 break;
5522
5523 case GL_TEXTURE_SRGB_DECODE_EXT:
5524 if (!context->getExtensions().textureSRGBDecode)
5525 {
Jamie Madill610640f2018-11-21 17:28:41 -05005526 context->validationError(GL_INVALID_ENUM,
5527 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005528 return false;
5529 }
5530 break;
5531
Yunchao Hebacaa712018-01-30 14:01:39 +08005532 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5533 if (context->getClientVersion() < Version(3, 1))
5534 {
Jamie Madille0472f32018-11-27 16:32:45 -05005535 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005536 return false;
5537 }
5538 break;
5539
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005540 case GL_GENERATE_MIPMAP:
5541 case GL_TEXTURE_CROP_RECT_OES:
5542 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5543 // after GL_OES_draw_texture functionality implemented
5544 if (context->getClientMajorVersion() > 1)
5545 {
Jamie Madille0472f32018-11-27 16:32:45 -05005546 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005547 return false;
5548 }
5549 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005550
5551 case GL_MEMORY_SIZE_ANGLE:
5552 if (!context->getExtensions().memorySize)
5553 {
Jamie Madille0472f32018-11-27 16:32:45 -05005554 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005555 return false;
5556 }
5557 break;
5558
Till Rathmannb8543632018-10-02 19:46:14 +02005559 case GL_TEXTURE_BORDER_COLOR:
5560 if (!context->getExtensions().textureBorderClamp)
5561 {
Jamie Madille0472f32018-11-27 16:32:45 -05005562 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005563 return false;
5564 }
5565 break;
5566
Jamie Madillbe849e42017-05-02 15:49:00 -04005567 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005568 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005569 return false;
5570 }
5571
5572 if (length)
5573 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005574 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005575 }
5576 return true;
5577}
5578
5579bool ValidateGetVertexAttribBase(Context *context,
5580 GLuint index,
5581 GLenum pname,
5582 GLsizei *length,
5583 bool pointer,
5584 bool pureIntegerEntryPoint)
5585{
5586 if (length)
5587 {
5588 *length = 0;
5589 }
5590
5591 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5592 {
Jamie Madill610640f2018-11-21 17:28:41 -05005593 context->validationError(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005594 return false;
5595 }
5596
5597 if (index >= context->getCaps().maxVertexAttributes)
5598 {
Jamie Madille0472f32018-11-27 16:32:45 -05005599 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005600 return false;
5601 }
5602
5603 if (pointer)
5604 {
5605 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5606 {
Jamie Madille0472f32018-11-27 16:32:45 -05005607 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005608 return false;
5609 }
5610 }
5611 else
5612 {
5613 switch (pname)
5614 {
5615 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5616 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5617 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5618 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5619 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5620 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5621 case GL_CURRENT_VERTEX_ATTRIB:
5622 break;
5623
5624 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5625 static_assert(
5626 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5627 "ANGLE extension enums not equal to GL enums.");
5628 if (context->getClientMajorVersion() < 3 &&
5629 !context->getExtensions().instancedArrays)
5630 {
Jamie Madill610640f2018-11-21 17:28:41 -05005631 context->validationError(GL_INVALID_ENUM,
5632 "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5633 "requires OpenGL ES 3.0 or "
5634 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005635 return false;
5636 }
5637 break;
5638
5639 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5640 if (context->getClientMajorVersion() < 3)
5641 {
Jamie Madill610640f2018-11-21 17:28:41 -05005642 context->validationError(
5643 GL_INVALID_ENUM, "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005644 return false;
5645 }
5646 break;
5647
5648 case GL_VERTEX_ATTRIB_BINDING:
5649 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5650 if (context->getClientVersion() < ES_3_1)
5651 {
Jamie Madill610640f2018-11-21 17:28:41 -05005652 context->validationError(GL_INVALID_ENUM,
5653 "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005654 return false;
5655 }
5656 break;
5657
5658 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005659 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005660 return false;
5661 }
5662 }
5663
5664 if (length)
5665 {
5666 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5667 {
5668 *length = 4;
5669 }
5670 else
5671 {
5672 *length = 1;
5673 }
5674 }
5675
5676 return true;
5677}
5678
Jamie Madill4928b7c2017-06-20 12:57:39 -04005679bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005680 GLint x,
5681 GLint y,
5682 GLsizei width,
5683 GLsizei height,
5684 GLenum format,
5685 GLenum type,
5686 GLsizei bufSize,
5687 GLsizei *length,
5688 GLsizei *columns,
5689 GLsizei *rows,
5690 void *pixels)
5691{
5692 if (length != nullptr)
5693 {
5694 *length = 0;
5695 }
5696 if (rows != nullptr)
5697 {
5698 *rows = 0;
5699 }
5700 if (columns != nullptr)
5701 {
5702 *columns = 0;
5703 }
5704
5705 if (width < 0 || height < 0)
5706 {
Jamie Madille0472f32018-11-27 16:32:45 -05005707 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005708 return false;
5709 }
5710
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005711 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005712
Jamie Madill427064d2018-04-13 16:20:34 -04005713 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005714 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005715 return false;
5716 }
5717
Jamie Madille98b1b52018-03-08 09:47:23 -05005718 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005719 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005720 return false;
5721 }
5722
Jamie Madill690c8eb2018-03-12 15:20:03 -04005723 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005724 ASSERT(framebuffer);
5725
5726 if (framebuffer->getReadBufferState() == GL_NONE)
5727 {
Jamie Madille0472f32018-11-27 16:32:45 -05005728 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005729 return false;
5730 }
5731
5732 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5733 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5734 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5735 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5736 // situation is an application error that would lead to a crash in ANGLE.
5737 if (readBuffer == nullptr)
5738 {
Jamie Madille0472f32018-11-27 16:32:45 -05005739 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005740 return false;
5741 }
5742
Martin Radev28031682017-07-28 14:47:56 +03005743 // ANGLE_multiview, Revision 1:
5744 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005745 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5746 // in the current read framebuffer is more than one.
5747 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005748 {
Jamie Madill610640f2018-11-21 17:28:41 -05005749 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
5750 "Attempting to read from a multi-view framebuffer.");
Martin Radev28031682017-07-28 14:47:56 +03005751 return false;
5752 }
5753
Geoff Lang280ba992017-04-18 16:30:58 -04005754 if (context->getExtensions().webglCompatibility)
5755 {
5756 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5757 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5758 // and type before validating the combination of format and type. However, the
5759 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5760 // verifies that GL_INVALID_OPERATION is generated.
5761 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5762 // dEQP/WebGL.
5763 if (!ValidReadPixelsFormatEnum(context, format))
5764 {
Jamie Madille0472f32018-11-27 16:32:45 -05005765 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005766 return false;
5767 }
5768
5769 if (!ValidReadPixelsTypeEnum(context, type))
5770 {
Jamie Madille0472f32018-11-27 16:32:45 -05005771 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005772 return false;
5773 }
5774 }
5775
Jamie Madill690c8eb2018-03-12 15:20:03 -04005776 GLenum currentFormat = GL_NONE;
5777 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5778
5779 GLenum currentType = GL_NONE;
5780 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5781
Jamie Madillbe849e42017-05-02 15:49:00 -04005782 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5783
5784 bool validFormatTypeCombination =
5785 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5786
5787 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5788 {
Jamie Madille0472f32018-11-27 16:32:45 -05005789 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005790 return false;
5791 }
5792
5793 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005794 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005795 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5796 {
5797 // ...the buffer object's data store is currently mapped.
Jamie Madill610640f2018-11-21 17:28:41 -05005798 context->validationError(GL_INVALID_OPERATION, "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005799 return false;
5800 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005801 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5802 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5803 {
Jamie Madille0472f32018-11-27 16:32:45 -05005804 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005805 return false;
5806 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005807
5808 // .. the data would be packed to the buffer object such that the memory writes required
5809 // would exceed the data store size.
5810 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005811 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005812 const auto &pack = context->getGLState().getPackState();
5813
Jamie Madillca2ff382018-07-11 09:01:17 -04005814 GLuint endByte = 0;
5815 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005816 {
Jamie Madille0472f32018-11-27 16:32:45 -05005817 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005818 return false;
5819 }
5820
Jamie Madillbe849e42017-05-02 15:49:00 -04005821 if (bufSize >= 0)
5822 {
5823 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5824 {
Jamie Madille0472f32018-11-27 16:32:45 -05005825 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005826 return false;
5827 }
5828 }
5829
5830 if (pixelPackBuffer != nullptr)
5831 {
5832 CheckedNumeric<size_t> checkedEndByte(endByte);
5833 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5834 checkedEndByte += checkedOffset;
5835
5836 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5837 {
5838 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005839 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005840 return false;
5841 }
5842 }
5843
5844 if (pixelPackBuffer == nullptr && length != nullptr)
5845 {
5846 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5847 {
Jamie Madille0472f32018-11-27 16:32:45 -05005848 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005849 return false;
5850 }
5851
5852 *length = static_cast<GLsizei>(endByte);
5853 }
5854
Geoff Langa953b522018-02-21 16:56:23 -05005855 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005856 angle::CheckedNumeric<int> clippedExtent(length);
5857 if (start < 0)
5858 {
5859 // "subtract" the area that is less than 0
5860 clippedExtent += start;
5861 }
5862
Geoff Langa953b522018-02-21 16:56:23 -05005863 angle::CheckedNumeric<int> readExtent = start;
5864 readExtent += length;
5865 if (!readExtent.IsValid())
5866 {
5867 return false;
5868 }
5869
5870 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005871 {
5872 // Subtract the region to the right of the read buffer
5873 clippedExtent -= (readExtent - bufferSize);
5874 }
5875
5876 if (!clippedExtent.IsValid())
5877 {
Geoff Langa953b522018-02-21 16:56:23 -05005878 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005879 }
5880
Geoff Langa953b522018-02-21 16:56:23 -05005881 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5882 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005883 };
5884
Geoff Langa953b522018-02-21 16:56:23 -05005885 GLsizei writtenColumns = 0;
5886 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5887 {
Jamie Madille0472f32018-11-27 16:32:45 -05005888 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005889 return false;
5890 }
5891
5892 GLsizei writtenRows = 0;
5893 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5894 {
Jamie Madille0472f32018-11-27 16:32:45 -05005895 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005896 return false;
5897 }
5898
Jamie Madillbe849e42017-05-02 15:49:00 -04005899 if (columns != nullptr)
5900 {
Geoff Langa953b522018-02-21 16:56:23 -05005901 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005902 }
5903
5904 if (rows != nullptr)
5905 {
Geoff Langa953b522018-02-21 16:56:23 -05005906 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005907 }
5908
5909 return true;
5910}
5911
5912template <typename ParamType>
5913bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005914 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005915 GLenum pname,
5916 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005917 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 const ParamType *params)
5919{
5920 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5921 {
Jamie Madille0472f32018-11-27 16:32:45 -05005922 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005923 return false;
5924 }
5925
5926 if (context->getTargetTexture(target) == nullptr)
5927 {
5928 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005929 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005930 return false;
5931 }
5932
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005933 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 if (bufSize >= 0 && bufSize < minBufSize)
5935 {
Jamie Madille0472f32018-11-27 16:32:45 -05005936 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005937 return false;
5938 }
5939
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005940 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5941 {
Jamie Madille0472f32018-11-27 16:32:45 -05005942 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005943 return false;
5944 }
5945
Jamie Madillbe849e42017-05-02 15:49:00 -04005946 switch (pname)
5947 {
5948 case GL_TEXTURE_WRAP_R:
5949 case GL_TEXTURE_SWIZZLE_R:
5950 case GL_TEXTURE_SWIZZLE_G:
5951 case GL_TEXTURE_SWIZZLE_B:
5952 case GL_TEXTURE_SWIZZLE_A:
5953 case GL_TEXTURE_BASE_LEVEL:
5954 case GL_TEXTURE_MAX_LEVEL:
5955 case GL_TEXTURE_COMPARE_MODE:
5956 case GL_TEXTURE_COMPARE_FUNC:
5957 case GL_TEXTURE_MIN_LOD:
5958 case GL_TEXTURE_MAX_LOD:
5959 if (context->getClientMajorVersion() < 3)
5960 {
Jamie Madille0472f32018-11-27 16:32:45 -05005961 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005962 return false;
5963 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005964 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 {
Jamie Madill610640f2018-11-21 17:28:41 -05005966 context->validationError(GL_INVALID_ENUM,
5967 "ES3 texture parameters are not "
5968 "available without "
5969 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005970 return false;
5971 }
5972 break;
5973
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005974 case GL_GENERATE_MIPMAP:
5975 case GL_TEXTURE_CROP_RECT_OES:
5976 if (context->getClientMajorVersion() > 1)
5977 {
Jamie Madille0472f32018-11-27 16:32:45 -05005978 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005979 return false;
5980 }
5981 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005982 default:
5983 break;
5984 }
5985
Olli Etuahod310a432018-08-24 15:40:23 +03005986 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005987 {
5988 switch (pname)
5989 {
5990 case GL_TEXTURE_MIN_FILTER:
5991 case GL_TEXTURE_MAG_FILTER:
5992 case GL_TEXTURE_WRAP_S:
5993 case GL_TEXTURE_WRAP_T:
5994 case GL_TEXTURE_WRAP_R:
5995 case GL_TEXTURE_MIN_LOD:
5996 case GL_TEXTURE_MAX_LOD:
5997 case GL_TEXTURE_COMPARE_MODE:
5998 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005999 case GL_TEXTURE_BORDER_COLOR:
Jamie Madill610640f2018-11-21 17:28:41 -05006000 context->validationError(GL_INVALID_ENUM,
6001 "Invalid parameter for 2D multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08006002 return false;
6003 }
6004 }
6005
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 switch (pname)
6007 {
6008 case GL_TEXTURE_WRAP_S:
6009 case GL_TEXTURE_WRAP_T:
6010 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006011 {
6012 bool restrictedWrapModes =
6013 target == TextureType::External || target == TextureType::Rectangle;
6014 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006016 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006017 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006018 }
6019 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006020
6021 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006022 {
6023 bool restrictedMinFilter =
6024 target == TextureType::External || target == TextureType::Rectangle;
6025 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04006026 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006027 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006028 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006029 }
6030 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006031
6032 case GL_TEXTURE_MAG_FILTER:
6033 if (!ValidateTextureMagFilterValue(context, params))
6034 {
6035 return false;
6036 }
6037 break;
6038
6039 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04006040 if (!context->getExtensions().textureUsage)
6041 {
Jamie Madille0472f32018-11-27 16:32:45 -05006042 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04006043 return false;
6044 }
6045
Jamie Madillbe849e42017-05-02 15:49:00 -04006046 switch (ConvertToGLenum(params[0]))
6047 {
6048 case GL_NONE:
6049 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
6050 break;
6051
6052 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006053 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006054 return false;
6055 }
6056 break;
6057
6058 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006059 {
6060 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6061 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006063 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006064 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006065 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
6066 }
6067 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006068
6069 case GL_TEXTURE_MIN_LOD:
6070 case GL_TEXTURE_MAX_LOD:
6071 // any value is permissible
6072 break;
6073
6074 case GL_TEXTURE_COMPARE_MODE:
6075 if (!ValidateTextureCompareModeValue(context, params))
6076 {
6077 return false;
6078 }
6079 break;
6080
6081 case GL_TEXTURE_COMPARE_FUNC:
6082 if (!ValidateTextureCompareFuncValue(context, params))
6083 {
6084 return false;
6085 }
6086 break;
6087
6088 case GL_TEXTURE_SWIZZLE_R:
6089 case GL_TEXTURE_SWIZZLE_G:
6090 case GL_TEXTURE_SWIZZLE_B:
6091 case GL_TEXTURE_SWIZZLE_A:
6092 switch (ConvertToGLenum(params[0]))
6093 {
6094 case GL_RED:
6095 case GL_GREEN:
6096 case GL_BLUE:
6097 case GL_ALPHA:
6098 case GL_ZERO:
6099 case GL_ONE:
6100 break;
6101
6102 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006103 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006104 return false;
6105 }
6106 break;
6107
6108 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006109 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 {
Jamie Madill610640f2018-11-21 17:28:41 -05006111 context->validationError(GL_INVALID_VALUE, "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006112 return false;
6113 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006114 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006115 {
Jamie Madill610640f2018-11-21 17:28:41 -05006116 context->validationError(GL_INVALID_OPERATION,
6117 "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 return false;
6119 }
Olli Etuahod310a432018-08-24 15:40:23 +03006120 if ((target == TextureType::_2DMultisample ||
6121 target == TextureType::_2DMultisampleArray) &&
6122 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006123 {
Jamie Madill610640f2018-11-21 17:28:41 -05006124 context->validationError(GL_INVALID_OPERATION,
6125 "Base level must be 0 for multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08006126 return false;
6127 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006128 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006129 {
Jamie Madill610640f2018-11-21 17:28:41 -05006130 context->validationError(GL_INVALID_OPERATION,
6131 "Base level must be 0 for rectangle textures.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006132 return false;
6133 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 break;
6135
6136 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006137 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006138 {
Jamie Madille0472f32018-11-27 16:32:45 -05006139 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006140 return false;
6141 }
6142 break;
6143
6144 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6145 if (context->getClientVersion() < Version(3, 1))
6146 {
Jamie Madille0472f32018-11-27 16:32:45 -05006147 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 return false;
6149 }
6150 switch (ConvertToGLenum(params[0]))
6151 {
6152 case GL_DEPTH_COMPONENT:
6153 case GL_STENCIL_INDEX:
6154 break;
6155
6156 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006157 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 return false;
6159 }
6160 break;
6161
6162 case GL_TEXTURE_SRGB_DECODE_EXT:
6163 if (!ValidateTextureSRGBDecodeValue(context, params))
6164 {
6165 return false;
6166 }
6167 break;
6168
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006169 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006170 if (context->getClientMajorVersion() > 1)
6171 {
Jamie Madille0472f32018-11-27 16:32:45 -05006172 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006173 return false;
6174 }
6175 break;
Till Rathmannb8543632018-10-02 19:46:14 +02006176
6177 case GL_TEXTURE_CROP_RECT_OES:
6178 if (context->getClientMajorVersion() > 1)
6179 {
Jamie Madille0472f32018-11-27 16:32:45 -05006180 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02006181 return false;
6182 }
6183 if (!vectorParams)
6184 {
Jamie Madille0472f32018-11-27 16:32:45 -05006185 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006186 return false;
6187 }
6188 break;
6189
6190 case GL_TEXTURE_BORDER_COLOR:
6191 if (!context->getExtensions().textureBorderClamp)
6192 {
Jamie Madille0472f32018-11-27 16:32:45 -05006193 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006194 return false;
6195 }
6196 if (!vectorParams)
6197 {
Jamie Madille0472f32018-11-27 16:32:45 -05006198 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006199 return false;
6200 }
6201 break;
6202
Jamie Madillbe849e42017-05-02 15:49:00 -04006203 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006204 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006205 return false;
6206 }
6207
6208 return true;
6209}
6210
Till Rathmannb8543632018-10-02 19:46:14 +02006211template bool ValidateTexParameterBase(Context *,
6212 TextureType,
6213 GLenum,
6214 GLsizei,
6215 bool,
6216 const GLfloat *);
6217template bool ValidateTexParameterBase(Context *,
6218 TextureType,
6219 GLenum,
6220 GLsizei,
6221 bool,
6222 const GLint *);
6223template bool ValidateTexParameterBase(Context *,
6224 TextureType,
6225 GLenum,
6226 GLsizei,
6227 bool,
6228 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006229
Jamie Madill5b772312018-03-08 20:28:32 -05006230bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006231{
6232 if (index >= MAX_VERTEX_ATTRIBS)
6233 {
Jamie Madille0472f32018-11-27 16:32:45 -05006234 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04006235 return false;
6236 }
6237
6238 return true;
6239}
6240
6241bool ValidateGetActiveUniformBlockivBase(Context *context,
6242 GLuint program,
6243 GLuint uniformBlockIndex,
6244 GLenum pname,
6245 GLsizei *length)
6246{
6247 if (length)
6248 {
6249 *length = 0;
6250 }
6251
6252 if (context->getClientMajorVersion() < 3)
6253 {
Jamie Madille0472f32018-11-27 16:32:45 -05006254 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04006255 return false;
6256 }
6257
6258 Program *programObject = GetValidProgram(context, program);
6259 if (!programObject)
6260 {
6261 return false;
6262 }
6263
6264 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6265 {
Jamie Madill610640f2018-11-21 17:28:41 -05006266 context->validationError(GL_INVALID_VALUE,
6267 "uniformBlockIndex exceeds active uniform block count.");
Jamie Madill12e957f2017-08-26 21:42:26 -04006268 return false;
6269 }
6270
6271 switch (pname)
6272 {
6273 case GL_UNIFORM_BLOCK_BINDING:
6274 case GL_UNIFORM_BLOCK_DATA_SIZE:
6275 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6276 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6277 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6278 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6279 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6280 break;
6281
6282 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006283 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04006284 return false;
6285 }
6286
6287 if (length)
6288 {
6289 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6290 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006291 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006292 programObject->getUniformBlockByIndex(uniformBlockIndex);
6293 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6294 }
6295 else
6296 {
6297 *length = 1;
6298 }
6299 }
6300
6301 return true;
6302}
6303
Jamie Madill9696d072017-08-26 23:19:57 -04006304template <typename ParamType>
6305bool ValidateSamplerParameterBase(Context *context,
6306 GLuint sampler,
6307 GLenum pname,
6308 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02006309 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04006310 ParamType *params)
6311{
6312 if (context->getClientMajorVersion() < 3)
6313 {
Jamie Madille0472f32018-11-27 16:32:45 -05006314 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006315 return false;
6316 }
6317
6318 if (!context->isSampler(sampler))
6319 {
Jamie Madille0472f32018-11-27 16:32:45 -05006320 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006321 return false;
6322 }
6323
Till Rathmannb8543632018-10-02 19:46:14 +02006324 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006325 if (bufSize >= 0 && bufSize < minBufSize)
6326 {
Jamie Madille0472f32018-11-27 16:32:45 -05006327 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006328 return false;
6329 }
6330
6331 switch (pname)
6332 {
6333 case GL_TEXTURE_WRAP_S:
6334 case GL_TEXTURE_WRAP_T:
6335 case GL_TEXTURE_WRAP_R:
6336 if (!ValidateTextureWrapModeValue(context, params, false))
6337 {
6338 return false;
6339 }
6340 break;
6341
6342 case GL_TEXTURE_MIN_FILTER:
6343 if (!ValidateTextureMinFilterValue(context, params, false))
6344 {
6345 return false;
6346 }
6347 break;
6348
6349 case GL_TEXTURE_MAG_FILTER:
6350 if (!ValidateTextureMagFilterValue(context, params))
6351 {
6352 return false;
6353 }
6354 break;
6355
6356 case GL_TEXTURE_MIN_LOD:
6357 case GL_TEXTURE_MAX_LOD:
6358 // any value is permissible
6359 break;
6360
6361 case GL_TEXTURE_COMPARE_MODE:
6362 if (!ValidateTextureCompareModeValue(context, params))
6363 {
6364 return false;
6365 }
6366 break;
6367
6368 case GL_TEXTURE_COMPARE_FUNC:
6369 if (!ValidateTextureCompareFuncValue(context, params))
6370 {
6371 return false;
6372 }
6373 break;
6374
6375 case GL_TEXTURE_SRGB_DECODE_EXT:
6376 if (!ValidateTextureSRGBDecodeValue(context, params))
6377 {
6378 return false;
6379 }
6380 break;
6381
Luc Ferron1b1a8642018-01-23 15:12:01 -05006382 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6383 {
6384 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6385 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6386 {
6387 return false;
6388 }
6389 }
6390 break;
6391
Till Rathmannb8543632018-10-02 19:46:14 +02006392 case GL_TEXTURE_BORDER_COLOR:
6393 if (!context->getExtensions().textureBorderClamp)
6394 {
Jamie Madille0472f32018-11-27 16:32:45 -05006395 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006396 return false;
6397 }
6398 if (!vectorParams)
6399 {
Jamie Madille0472f32018-11-27 16:32:45 -05006400 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006401 return false;
6402 }
6403 break;
6404
Jamie Madill9696d072017-08-26 23:19:57 -04006405 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006406 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006407 return false;
6408 }
6409
6410 return true;
6411}
6412
Till Rathmannb8543632018-10-02 19:46:14 +02006413template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6414template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6415template bool ValidateSamplerParameterBase(Context *,
6416 GLuint,
6417 GLenum,
6418 GLsizei,
6419 bool,
6420 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006421
6422bool ValidateGetSamplerParameterBase(Context *context,
6423 GLuint sampler,
6424 GLenum pname,
6425 GLsizei *length)
6426{
6427 if (length)
6428 {
6429 *length = 0;
6430 }
6431
6432 if (context->getClientMajorVersion() < 3)
6433 {
Jamie Madille0472f32018-11-27 16:32:45 -05006434 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006435 return false;
6436 }
6437
6438 if (!context->isSampler(sampler))
6439 {
Jamie Madille0472f32018-11-27 16:32:45 -05006440 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006441 return false;
6442 }
6443
6444 switch (pname)
6445 {
6446 case GL_TEXTURE_WRAP_S:
6447 case GL_TEXTURE_WRAP_T:
6448 case GL_TEXTURE_WRAP_R:
6449 case GL_TEXTURE_MIN_FILTER:
6450 case GL_TEXTURE_MAG_FILTER:
6451 case GL_TEXTURE_MIN_LOD:
6452 case GL_TEXTURE_MAX_LOD:
6453 case GL_TEXTURE_COMPARE_MODE:
6454 case GL_TEXTURE_COMPARE_FUNC:
6455 break;
6456
Luc Ferron1b1a8642018-01-23 15:12:01 -05006457 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6458 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6459 {
6460 return false;
6461 }
6462 break;
6463
Jamie Madill9696d072017-08-26 23:19:57 -04006464 case GL_TEXTURE_SRGB_DECODE_EXT:
6465 if (!context->getExtensions().textureSRGBDecode)
6466 {
Jamie Madill610640f2018-11-21 17:28:41 -05006467 context->validationError(GL_INVALID_ENUM,
6468 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madill9696d072017-08-26 23:19:57 -04006469 return false;
6470 }
6471 break;
6472
Till Rathmannb8543632018-10-02 19:46:14 +02006473 case GL_TEXTURE_BORDER_COLOR:
6474 if (!context->getExtensions().textureBorderClamp)
6475 {
Jamie Madille0472f32018-11-27 16:32:45 -05006476 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006477 return false;
6478 }
6479 break;
6480
Jamie Madill9696d072017-08-26 23:19:57 -04006481 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006482 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006483 return false;
6484 }
6485
6486 if (length)
6487 {
Till Rathmannb8543632018-10-02 19:46:14 +02006488 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006489 }
6490 return true;
6491}
6492
6493bool ValidateGetInternalFormativBase(Context *context,
6494 GLenum target,
6495 GLenum internalformat,
6496 GLenum pname,
6497 GLsizei bufSize,
6498 GLsizei *numParams)
6499{
6500 if (numParams)
6501 {
6502 *numParams = 0;
6503 }
6504
6505 if (context->getClientMajorVersion() < 3)
6506 {
Jamie Madille0472f32018-11-27 16:32:45 -05006507 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006508 return false;
6509 }
6510
6511 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006512 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006513 {
Jamie Madill610640f2018-11-21 17:28:41 -05006514 context->validationError(GL_INVALID_ENUM, "Internal format is not renderable.");
Jamie Madill9696d072017-08-26 23:19:57 -04006515 return false;
6516 }
6517
6518 switch (target)
6519 {
6520 case GL_RENDERBUFFER:
6521 break;
6522
6523 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006524 if (context->getClientVersion() < ES_3_1 &&
6525 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006526 {
Jamie Madill610640f2018-11-21 17:28:41 -05006527 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006528 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006529 return false;
6530 }
6531 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006532 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6533 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006534 {
Jamie Madille0472f32018-11-27 16:32:45 -05006535 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006536 return false;
6537 }
6538 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006539 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006540 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006541 return false;
6542 }
6543
6544 if (bufSize < 0)
6545 {
Jamie Madille0472f32018-11-27 16:32:45 -05006546 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006547 return false;
6548 }
6549
6550 GLsizei maxWriteParams = 0;
6551 switch (pname)
6552 {
6553 case GL_NUM_SAMPLE_COUNTS:
6554 maxWriteParams = 1;
6555 break;
6556
6557 case GL_SAMPLES:
6558 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6559 break;
6560
6561 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006562 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006563 return false;
6564 }
6565
6566 if (numParams)
6567 {
6568 // glGetInternalFormativ will not overflow bufSize
6569 *numParams = std::min(bufSize, maxWriteParams);
6570 }
6571
6572 return true;
6573}
6574
Jamie Madille98b1b52018-03-08 09:47:23 -05006575bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6576{
Jamie Madill427064d2018-04-13 16:20:34 -04006577 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006578 {
Jamie Madille0472f32018-11-27 16:32:45 -05006579 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006580 return false;
6581 }
6582 return true;
6583}
6584
Lingfeng Yang038dd532018-03-29 17:31:52 -07006585bool ValidateMultitextureUnit(Context *context, GLenum texture)
6586{
6587 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6588 {
Jamie Madille0472f32018-11-27 16:32:45 -05006589 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006590 return false;
6591 }
6592 return true;
6593}
6594
Olli Etuahod310a432018-08-24 15:40:23 +03006595bool ValidateTexStorageMultisample(Context *context,
6596 TextureType target,
6597 GLsizei samples,
6598 GLint internalFormat,
6599 GLsizei width,
6600 GLsizei height)
6601{
6602 const Caps &caps = context->getCaps();
6603 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6604 static_cast<GLuint>(height) > caps.max2DTextureSize)
6605 {
Jamie Madille0472f32018-11-27 16:32:45 -05006606 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006607 return false;
6608 }
6609
6610 if (samples == 0)
6611 {
Jamie Madille0472f32018-11-27 16:32:45 -05006612 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006613 return false;
6614 }
6615
6616 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6617 if (!formatCaps.textureAttachment)
6618 {
Jamie Madille0472f32018-11-27 16:32:45 -05006619 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006620 return false;
6621 }
6622
6623 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6624 // is one of the unsized base internalformats listed in table 8.11.
6625 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6626 if (formatInfo.internalFormat == GL_NONE)
6627 {
Jamie Madille0472f32018-11-27 16:32:45 -05006628 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006629 return false;
6630 }
6631
6632 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6633 {
Jamie Madille0472f32018-11-27 16:32:45 -05006634 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006635 return false;
6636 }
6637
6638 Texture *texture = context->getTargetTexture(target);
6639 if (!texture || texture->id() == 0)
6640 {
Jamie Madille0472f32018-11-27 16:32:45 -05006641 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006642 return false;
6643 }
6644
6645 if (texture->getImmutableFormat())
6646 {
Jamie Madille0472f32018-11-27 16:32:45 -05006647 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006648 return false;
6649 }
6650 return true;
6651}
6652
Yizhou Jiang7818a852018-09-06 15:02:04 +08006653bool ValidateTexStorage2DMultisampleBase(Context *context,
6654 TextureType target,
6655 GLsizei samples,
6656 GLint internalFormat,
6657 GLsizei width,
6658 GLsizei height)
6659{
6660 if (target != TextureType::_2DMultisample)
6661 {
Jamie Madille0472f32018-11-27 16:32:45 -05006662 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006663 return false;
6664 }
6665
6666 if (width < 1 || height < 1)
6667 {
Jamie Madille0472f32018-11-27 16:32:45 -05006668 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006669 return false;
6670 }
6671
6672 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6673}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006674
6675bool ValidateGetTexLevelParameterBase(Context *context,
6676 TextureTarget target,
6677 GLint level,
6678 GLenum pname,
6679 GLsizei *length)
6680{
6681
6682 if (length)
6683 {
6684 *length = 0;
6685 }
6686
6687 TextureType type = TextureTargetToType(target);
6688
6689 if (!ValidTexLevelDestinationTarget(context, type))
6690 {
Jamie Madille0472f32018-11-27 16:32:45 -05006691 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006692 return false;
6693 }
6694
6695 if (context->getTargetTexture(type) == nullptr)
6696 {
Jamie Madill610640f2018-11-21 17:28:41 -05006697 context->validationError(GL_INVALID_ENUM, "No texture bound.");
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006698 return false;
6699 }
6700
6701 if (!ValidMipLevel(context, type, level))
6702 {
Jamie Madille0472f32018-11-27 16:32:45 -05006703 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006704 return false;
6705 }
6706
6707 switch (pname)
6708 {
6709 case GL_TEXTURE_RED_TYPE:
6710 case GL_TEXTURE_GREEN_TYPE:
6711 case GL_TEXTURE_BLUE_TYPE:
6712 case GL_TEXTURE_ALPHA_TYPE:
6713 case GL_TEXTURE_DEPTH_TYPE:
6714 break;
6715 case GL_TEXTURE_RED_SIZE:
6716 case GL_TEXTURE_GREEN_SIZE:
6717 case GL_TEXTURE_BLUE_SIZE:
6718 case GL_TEXTURE_ALPHA_SIZE:
6719 case GL_TEXTURE_DEPTH_SIZE:
6720 case GL_TEXTURE_STENCIL_SIZE:
6721 case GL_TEXTURE_SHARED_SIZE:
6722 break;
6723 case GL_TEXTURE_INTERNAL_FORMAT:
6724 case GL_TEXTURE_WIDTH:
6725 case GL_TEXTURE_HEIGHT:
6726 case GL_TEXTURE_DEPTH:
6727 break;
6728 case GL_TEXTURE_SAMPLES:
6729 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6730 break;
6731 case GL_TEXTURE_COMPRESSED:
6732 break;
6733 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006734 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006735 return false;
6736 }
6737
6738 if (length)
6739 {
6740 *length = 1;
6741 }
6742 return true;
6743}
Jamie Madillc29968b2016-01-20 11:17:23 -05006744} // namespace gl