blob: cddee6cca83d918208fe1bfeeb7d4bf711ebd1ac [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,
Jamie Madill8dc27f92018-11-29 11:45:44 -0500636 DrawElementsType type,
Jamie Madillbe849e42017-05-02 15:49:00 -0400637 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 Madill8dc27f92018-11-29 11:45:44 -05002962bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, DrawElementsType type)
Jamie Madillfd716582014-06-06 17:09:04 -04002963{
Jamie Madill8dc27f92018-11-29 11:45:44 -05002964 if (!context->getStateCache().isValidDrawElementsType(type))
Jamie Madill250d33f2014-06-06 17:09:03 -04002965 {
Jamie Madill8dc27f92018-11-29 11:45:44 -05002966 if (type == DrawElementsType::UnsignedInt)
2967 {
Jamie Madille0472f32018-11-27 16:32:45 -05002968 context->validationError(GL_INVALID_ENUM, kTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002969 return false;
Jamie Madill8dc27f92018-11-29 11:45:44 -05002970 }
2971
2972 ASSERT(type == DrawElementsType::InvalidEnum);
2973 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
2974 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002975 }
2976
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002977 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002978
Jamie Madill43da7c42018-08-01 11:34:49 -04002979 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002980 if (curTransformFeedback && curTransformFeedback->isActive() &&
2981 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002982 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002983 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2984 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2985 if (context->getExtensions().geometryShader)
2986 {
2987 if (!ValidateTransformFeedbackPrimitiveMode(
2988 context, curTransformFeedback->getPrimitiveMode(), mode))
2989 {
Jamie Madille0472f32018-11-27 16:32:45 -05002990 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002991 return false;
2992 }
2993 }
2994 else
2995 {
2996 // It is an invalid operation to call DrawElements, DrawRangeElements or
2997 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
2998 // 86)
Jamie Madill610640f2018-11-21 17:28:41 -05002999 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05003000 kUnsupportedDrawModeForTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003001 return false;
3002 }
Jamie Madill250d33f2014-06-06 17:09:03 -04003003 }
3004
Jiajia Qind9671222016-11-29 16:30:31 +08003005 return true;
3006}
3007
Jamie Madill5b772312018-03-08 20:28:32 -05003008bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003009 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003010 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003011 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04003012 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003013 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08003014{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003015 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003016 return false;
3017
3018 const State &state = context->getGLState();
3019
Corentin Wallez170efbf2017-05-02 13:45:01 -04003020 if (!ValidateDrawBase(context, mode, count))
3021 {
3022 return false;
3023 }
3024
Jamie Madill43da7c42018-08-01 11:34:49 -04003025 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003026 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003027
Jamie Madill8dc27f92018-11-29 11:45:44 -05003028 GLuint typeBytes = GetDrawElementsTypeSize(type);
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003029 ASSERT(isPow2(typeBytes) && typeBytes > 0);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003030
3031 if (context->getExtensions().webglCompatibility)
3032 {
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003033 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3034 {
3035 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3036 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3037 // data type passed to the call, or an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003038 context->validationError(GL_INVALID_OPERATION, kOffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003039 return false;
3040 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003041
3042 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3043 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3044 // error is generated.
3045 if (reinterpret_cast<intptr_t>(indices) < 0)
3046 {
Jamie Madille0472f32018-11-27 16:32:45 -05003047 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003048 return false;
3049 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003050
Brandon Jones2a018152018-06-08 15:59:26 -07003051 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003052 {
3053 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003054 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3055 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Jamie Madille0472f32018-11-27 16:32:45 -05003056 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003057 return false;
3058 }
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003059
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003060 if (elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
James Darpiniane8a93c62018-01-04 18:02:24 -08003061 {
Jamie Madill610640f2018-11-21 17:28:41 -05003062 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05003063 kElementArrayBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003064 return false;
3065 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003066 }
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003067 else
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003068 {
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003069 if (elementArrayBuffer)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003070 {
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003071 if (elementArrayBuffer->isMapped())
3072 {
3073 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3074 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the
3075 // WebGL 2.0 API. https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
3076 context->validationError(GL_INVALID_OPERATION, "Index buffer is mapped.");
3077 return false;
3078 }
3079 }
3080 else if (!context->getGLState().areClientArraysEnabled())
3081 {
3082 context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003083 return false;
3084 }
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003085 }
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003086
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003087 if (count > 0)
3088 {
3089 if (!elementArrayBuffer)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003090 {
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003091 if (!indices)
3092 {
3093 // This is an application error that would normally result in a crash, but we catch
3094 // it and return an error
3095 context->validationError(GL_INVALID_OPERATION,
3096 "No element array buffer and no pointer.");
3097 return false;
3098 }
3099 }
3100 else
3101 {
3102 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3103 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3104 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3105 constexpr uint64_t kMaxTypeSize = 8;
3106 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3107 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3108 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3109
3110 uint64_t typeSize = typeBytes;
3111 uint64_t elementCount = static_cast<uint64_t>(count);
3112 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3113
3114 // Doing the multiplication here is overflow-safe
3115 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3116
3117 // The offset can be any value, check for overflows
3118 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3119 if (elementDataSizeNoOffset > kUint64Max - offset)
3120 {
3121 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
3122 return false;
3123 }
3124
3125 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3126 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
3127 {
3128 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
3129 return false;
3130 }
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003131 }
3132
Jamie Madill2c0d6a92018-11-28 14:03:58 -05003133 if (!context->getExtensions().robustBufferAccessBehavior && primcount > 0)
3134 {
3135 // Use the parameter buffer to retrieve and cache the index range.
3136 IndexRange indexRange;
3137 ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
3138
3139 // If we use an index greater than our maximum supported index range, return an error.
3140 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
3141 // always return an error if possible here.
3142 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
3143 {
3144 context->validationError(GL_INVALID_OPERATION, kExceedsMaxElement);
3145 return false;
3146 }
3147
3148 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
3149 {
3150 return false;
3151 }
3152
3153 // No op if there are no real indices in the index data (all are primitive restart).
3154 return (indexRange.vertexIndexCount > 0);
3155 }
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003156 }
3157
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003158 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003159}
3160
Jamie Madill5b772312018-03-08 20:28:32 -05003161bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003162 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003163 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003164 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04003165 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003166 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003167{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003168 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003169}
3170
Geoff Lang3edfe032015-09-04 16:38:24 -04003171bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003172 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003173 GLsizei count,
Jamie Madill8dc27f92018-11-29 11:45:44 -05003174 DrawElementsType type,
Jamie Madill876429b2017-04-20 15:46:24 -04003175 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003176 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003177{
Geoff Lang63c5a592017-09-27 14:08:16 -04003178 if (!context->getExtensions().instancedArrays)
3179 {
Jamie Madille0472f32018-11-27 16:32:45 -05003180 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04003181 return false;
3182 }
3183
Corentin Wallez170efbf2017-05-02 13:45:01 -04003184 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003185 {
3186 return false;
3187 }
3188
Corentin Wallez0dc97812017-06-22 14:38:44 -04003189 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003190}
3191
He Yunchaoced53ae2016-11-29 15:00:51 +08003192bool ValidateFramebufferTextureBase(Context *context,
3193 GLenum target,
3194 GLenum attachment,
3195 GLuint texture,
3196 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003197{
Geoff Lange8afa902017-09-27 15:00:43 -04003198 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003199 {
Jamie Madille0472f32018-11-27 16:32:45 -05003200 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003201 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003202 }
3203
3204 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003205 {
3206 return false;
3207 }
3208
Jamie Madill55ec3b12014-07-03 10:38:57 -04003209 if (texture != 0)
3210 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003211 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003212
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003213 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003214 {
Jamie Madille0472f32018-11-27 16:32:45 -05003215 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04003216 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003217 }
3218
3219 if (level < 0)
3220 {
Jamie Madille0472f32018-11-27 16:32:45 -05003221 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04003222 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003223 }
3224 }
3225
Jamie Madill43da7c42018-08-01 11:34:49 -04003226 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003227 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003228
Jamie Madill84115c92015-04-23 15:00:07 -04003229 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003230 {
Jamie Madille0472f32018-11-27 16:32:45 -05003231 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003232 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003233 }
3234
3235 return true;
3236}
3237
Geoff Langb1196682014-07-23 13:47:29 -04003238bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003239{
3240 if (program == 0)
3241 {
Jamie Madille0472f32018-11-27 16:32:45 -05003242 context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04003243 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003244 }
3245
Jamie Madill43da7c42018-08-01 11:34:49 -04003246 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003247 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003248 {
3249 return false;
3250 }
3251
Jamie Madill0063c512014-08-25 15:47:53 -04003252 if (!programObject || !programObject->isLinked())
3253 {
Jamie Madille0472f32018-11-27 16:32:45 -05003254 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003255 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003256 }
3257
Geoff Lang7dd2e102014-11-10 15:19:26 -05003258 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003259 {
Jamie Madille0472f32018-11-27 16:32:45 -05003260 context->validationError(GL_INVALID_OPERATION, kInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003261 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003262 }
3263
Jamie Madill0063c512014-08-25 15:47:53 -04003264 return true;
3265}
3266
Geoff Langf41d0ee2016-10-07 13:04:23 -04003267static bool ValidateSizedGetUniform(Context *context,
3268 GLuint program,
3269 GLint location,
3270 GLsizei bufSize,
3271 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003272{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003273 if (length)
3274 {
3275 *length = 0;
3276 }
3277
Jamie Madill78f41802014-08-25 15:47:55 -04003278 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003279 {
Jamie Madill78f41802014-08-25 15:47:55 -04003280 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003281 }
3282
Geoff Langf41d0ee2016-10-07 13:04:23 -04003283 if (bufSize < 0)
3284 {
Jamie Madille0472f32018-11-27 16:32:45 -05003285 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003286 return false;
3287 }
3288
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003289 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003290 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003291
Jamie Madill78f41802014-08-25 15:47:55 -04003292 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003293 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003294 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003295 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003296 {
Jamie Madille0472f32018-11-27 16:32:45 -05003297 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003298 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003299 }
3300
Geoff Langf41d0ee2016-10-07 13:04:23 -04003301 if (length)
3302 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003303 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003304 }
3305
Jamie Madill0063c512014-08-25 15:47:53 -04003306 return true;
3307}
3308
He Yunchaoced53ae2016-11-29 15:00:51 +08003309bool ValidateGetnUniformfvEXT(Context *context,
3310 GLuint program,
3311 GLint location,
3312 GLsizei bufSize,
3313 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003314{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003315 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003316}
3317
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003318bool ValidateGetnUniformfvRobustANGLE(Context *context,
3319 GLuint program,
3320 GLint location,
3321 GLsizei bufSize,
3322 GLsizei *length,
3323 GLfloat *params)
3324{
3325 UNIMPLEMENTED();
3326 return false;
3327}
3328
He Yunchaoced53ae2016-11-29 15:00:51 +08003329bool ValidateGetnUniformivEXT(Context *context,
3330 GLuint program,
3331 GLint location,
3332 GLsizei bufSize,
3333 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003334{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003335 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3336}
3337
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003338bool ValidateGetnUniformivRobustANGLE(Context *context,
3339 GLuint program,
3340 GLint location,
3341 GLsizei bufSize,
3342 GLsizei *length,
3343 GLint *params)
3344{
3345 UNIMPLEMENTED();
3346 return false;
3347}
3348
3349bool ValidateGetnUniformuivRobustANGLE(Context *context,
3350 GLuint program,
3351 GLint location,
3352 GLsizei bufSize,
3353 GLsizei *length,
3354 GLuint *params)
3355{
3356 UNIMPLEMENTED();
3357 return false;
3358}
3359
Geoff Langf41d0ee2016-10-07 13:04:23 -04003360bool ValidateGetUniformfvRobustANGLE(Context *context,
3361 GLuint program,
3362 GLint location,
3363 GLsizei bufSize,
3364 GLsizei *length,
3365 GLfloat *params)
3366{
3367 if (!ValidateRobustEntryPoint(context, bufSize))
3368 {
3369 return false;
3370 }
3371
Brandon Jonesd1049182018-03-28 10:02:20 -07003372 GLsizei writeLength = 0;
3373
Geoff Langf41d0ee2016-10-07 13:04:23 -04003374 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003375 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3376 {
3377 return false;
3378 }
3379
3380 SetRobustLengthParam(length, writeLength);
3381
3382 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003383}
3384
3385bool ValidateGetUniformivRobustANGLE(Context *context,
3386 GLuint program,
3387 GLint location,
3388 GLsizei bufSize,
3389 GLsizei *length,
3390 GLint *params)
3391{
3392 if (!ValidateRobustEntryPoint(context, bufSize))
3393 {
3394 return false;
3395 }
3396
Brandon Jonesd1049182018-03-28 10:02:20 -07003397 GLsizei writeLength = 0;
3398
Geoff Langf41d0ee2016-10-07 13:04:23 -04003399 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003400 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3401 {
3402 return false;
3403 }
3404
3405 SetRobustLengthParam(length, writeLength);
3406
3407 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003408}
3409
3410bool ValidateGetUniformuivRobustANGLE(Context *context,
3411 GLuint program,
3412 GLint location,
3413 GLsizei bufSize,
3414 GLsizei *length,
3415 GLuint *params)
3416{
3417 if (!ValidateRobustEntryPoint(context, bufSize))
3418 {
3419 return false;
3420 }
3421
3422 if (context->getClientMajorVersion() < 3)
3423 {
Jamie Madille0472f32018-11-27 16:32:45 -05003424 context->validationError(GL_INVALID_OPERATION, kES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003425 return false;
3426 }
3427
Brandon Jonesd1049182018-03-28 10:02:20 -07003428 GLsizei writeLength = 0;
3429
Geoff Langf41d0ee2016-10-07 13:04:23 -04003430 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003431 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3432 {
3433 return false;
3434 }
3435
3436 SetRobustLengthParam(length, writeLength);
3437
3438 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003439}
3440
He Yunchaoced53ae2016-11-29 15:00:51 +08003441bool ValidateDiscardFramebufferBase(Context *context,
3442 GLenum target,
3443 GLsizei numAttachments,
3444 const GLenum *attachments,
3445 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003446{
3447 if (numAttachments < 0)
3448 {
Jamie Madille0472f32018-11-27 16:32:45 -05003449 context->validationError(GL_INVALID_VALUE, kNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003450 return false;
3451 }
3452
3453 for (GLsizei i = 0; i < numAttachments; ++i)
3454 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003455 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003456 {
3457 if (defaultFramebuffer)
3458 {
Jamie Madille0472f32018-11-27 16:32:45 -05003459 context->validationError(GL_INVALID_ENUM, kDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003460 return false;
3461 }
3462
3463 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3464 {
Jamie Madill610640f2018-11-21 17:28:41 -05003465 context->validationError(GL_INVALID_OPERATION,
3466 "Requested color attachment is "
3467 "greater than the maximum supported "
3468 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003469 return false;
3470 }
3471 }
3472 else
3473 {
3474 switch (attachments[i])
3475 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003476 case GL_DEPTH_ATTACHMENT:
3477 case GL_STENCIL_ATTACHMENT:
3478 case GL_DEPTH_STENCIL_ATTACHMENT:
3479 if (defaultFramebuffer)
3480 {
Jamie Madill610640f2018-11-21 17:28:41 -05003481 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003482 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003483 return false;
3484 }
3485 break;
3486 case GL_COLOR:
3487 case GL_DEPTH:
3488 case GL_STENCIL:
3489 if (!defaultFramebuffer)
3490 {
Jamie Madill610640f2018-11-21 17:28:41 -05003491 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05003492 kDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003493 return false;
3494 }
3495 break;
3496 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003497 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003498 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003499 }
3500 }
3501 }
3502
3503 return true;
3504}
3505
Austin Kinross6ee1e782015-05-29 17:05:37 -07003506bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3507{
Jamie Madill007530e2017-12-28 14:27:04 -05003508 if (!context->getExtensions().debugMarker)
3509 {
3510 // The debug marker calls should not set error state
3511 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003512 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003513 return false;
3514 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003515
Jamie Madill007530e2017-12-28 14:27:04 -05003516 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003517 if (length < 0)
3518 {
3519 return false;
3520 }
3521
3522 if (marker == nullptr)
3523 {
3524 return false;
3525 }
3526
3527 return true;
3528}
3529
3530bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3531{
Jamie Madill007530e2017-12-28 14:27:04 -05003532 if (!context->getExtensions().debugMarker)
3533 {
3534 // The debug marker calls should not set error state
3535 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05003536 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003537 return false;
3538 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003539
Jamie Madill007530e2017-12-28 14:27:04 -05003540 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003541 if (length < 0)
3542 {
3543 return false;
3544 }
3545
3546 if (length > 0 && marker == nullptr)
3547 {
3548 return false;
3549 }
3550
3551 return true;
3552}
3553
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003554bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003555{
Geoff Langa8406172015-07-21 16:53:39 -04003556 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3557 {
Jamie Madille0472f32018-11-27 16:32:45 -05003558 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003559 return false;
3560 }
3561
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003562 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003563 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003564 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003565 if (!context->getExtensions().eglImage)
3566 {
Jamie Madill610640f2018-11-21 17:28:41 -05003567 context->validationError(GL_INVALID_ENUM,
3568 "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003569 }
3570 break;
3571
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003572 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003573 if (!context->getExtensions().eglImageExternal)
3574 {
Jamie Madill610640f2018-11-21 17:28:41 -05003575 context->validationError(GL_INVALID_ENUM,
3576 "GL_TEXTURE_EXTERNAL_OES texture target "
3577 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003578 }
Geoff Langa8406172015-07-21 16:53:39 -04003579 break;
3580
3581 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003582 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003583 return false;
3584 }
3585
Rafael Cintron05a449a2018-06-20 18:08:04 -07003586 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003587
Jamie Madill61e16b42017-06-19 11:13:23 -04003588 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003589 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003590 {
Jamie Madill610640f2018-11-21 17:28:41 -05003591 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003592 return false;
3593 }
3594
Jamie Madill007530e2017-12-28 14:27:04 -05003595 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003596 {
Jamie Madill610640f2018-11-21 17:28:41 -05003597 context->validationError(GL_INVALID_OPERATION,
3598 "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003599 return false;
3600 }
3601
Yuly Novikov2eb54072018-08-22 16:41:26 -04003602 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003603 {
Jamie Madill610640f2018-11-21 17:28:41 -05003604 context->validationError(GL_INVALID_OPERATION,
3605 "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003606 return false;
3607 }
3608
Geoff Langdcab33b2015-07-21 13:03:16 -04003609 return true;
3610}
3611
3612bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003613 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003614 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003615{
Geoff Langa8406172015-07-21 16:53:39 -04003616 if (!context->getExtensions().eglImage)
3617 {
Jamie Madille0472f32018-11-27 16:32:45 -05003618 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003619 return false;
3620 }
3621
3622 switch (target)
3623 {
3624 case GL_RENDERBUFFER:
3625 break;
3626
3627 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003628 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003629 return false;
3630 }
3631
Rafael Cintron05a449a2018-06-20 18:08:04 -07003632 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003633
Jamie Madill61e16b42017-06-19 11:13:23 -04003634 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003635 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003636 {
Jamie Madill610640f2018-11-21 17:28:41 -05003637 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003638 return false;
3639 }
3640
Yuly Novikov2eb54072018-08-22 16:41:26 -04003641 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003642 {
Jamie Madill610640f2018-11-21 17:28:41 -05003643 context->validationError(GL_INVALID_OPERATION,
3644 "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003645 return false;
3646 }
3647
Geoff Langdcab33b2015-07-21 13:03:16 -04003648 return true;
3649}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003650
3651bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3652{
Geoff Lang36167ab2015-12-07 10:27:14 -05003653 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003654 {
3655 // The default VAO should always exist
3656 ASSERT(array != 0);
Jamie Madille0472f32018-11-27 16:32:45 -05003657 context->validationError(GL_INVALID_OPERATION, kInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003658 return false;
3659 }
3660
3661 return true;
3662}
3663
Geoff Langc5629752015-12-07 16:29:04 -05003664bool ValidateProgramBinaryBase(Context *context,
3665 GLuint program,
3666 GLenum binaryFormat,
3667 const void *binary,
3668 GLint length)
3669{
3670 Program *programObject = GetValidProgram(context, program);
3671 if (programObject == nullptr)
3672 {
3673 return false;
3674 }
3675
3676 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3677 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3678 programBinaryFormats.end())
3679 {
Jamie Madill610640f2018-11-21 17:28:41 -05003680 context->validationError(GL_INVALID_ENUM, "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003681 return false;
3682 }
3683
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003684 if (context->hasActiveTransformFeedback(program))
3685 {
3686 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05003687 context->validationError(GL_INVALID_OPERATION,
3688 "Cannot change program binary while program "
3689 "is associated with an active transform "
3690 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003691 return false;
3692 }
3693
Geoff Langc5629752015-12-07 16:29:04 -05003694 return true;
3695}
3696
3697bool ValidateGetProgramBinaryBase(Context *context,
3698 GLuint program,
3699 GLsizei bufSize,
3700 GLsizei *length,
3701 GLenum *binaryFormat,
3702 void *binary)
3703{
3704 Program *programObject = GetValidProgram(context, program);
3705 if (programObject == nullptr)
3706 {
3707 return false;
3708 }
3709
3710 if (!programObject->isLinked())
3711 {
Jamie Madille0472f32018-11-27 16:32:45 -05003712 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003713 return false;
3714 }
3715
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003716 if (context->getCaps().programBinaryFormats.empty())
3717 {
Jamie Madill610640f2018-11-21 17:28:41 -05003718 context->validationError(GL_INVALID_OPERATION, "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003719 return false;
3720 }
3721
Geoff Langc5629752015-12-07 16:29:04 -05003722 return true;
3723}
Jamie Madillc29968b2016-01-20 11:17:23 -05003724
Jamie Madill5b772312018-03-08 20:28:32 -05003725bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003726{
3727 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003728 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003729 {
Jamie Madille0472f32018-11-27 16:32:45 -05003730 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003731 return false;
3732 }
3733 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3734 {
Jamie Madille0472f32018-11-27 16:32:45 -05003735 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003736 return false;
3737 }
3738
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003739 ASSERT(context->getGLState().getDrawFramebuffer());
3740 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003741 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3742
3743 // This should come first before the check for the default frame buffer
3744 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3745 // rather than INVALID_OPERATION
3746 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3747 {
3748 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3749
3750 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003751 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3752 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003753 {
3754 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003755 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3756 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3757 // 3.1 is still a bit ambiguous about the error, but future specs are
3758 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madill610640f2018-11-21 17:28:41 -05003759 context->validationError(GL_INVALID_ENUM, "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003760 return false;
3761 }
3762 else if (bufs[colorAttachment] >= maxColorAttachment)
3763 {
Jamie Madill610640f2018-11-21 17:28:41 -05003764 context->validationError(GL_INVALID_OPERATION,
3765 "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003766 return false;
3767 }
3768 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3769 frameBufferId != 0)
3770 {
3771 // INVALID_OPERATION-GL is bound to buffer and ith argument
3772 // is not COLOR_ATTACHMENTi or NONE
Jamie Madill610640f2018-11-21 17:28:41 -05003773 context->validationError(GL_INVALID_OPERATION,
3774 "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003775 return false;
3776 }
3777 }
3778
3779 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3780 // and n is not 1 or bufs is bound to value other than BACK and NONE
3781 if (frameBufferId == 0)
3782 {
3783 if (n != 1)
3784 {
Jamie Madill610640f2018-11-21 17:28:41 -05003785 context->validationError(GL_INVALID_OPERATION,
3786 "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003787 return false;
3788 }
3789
3790 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3791 {
Jamie Madill610640f2018-11-21 17:28:41 -05003792 context->validationError(
3793 GL_INVALID_OPERATION,
3794 "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003795 return false;
3796 }
3797 }
3798
3799 return true;
3800}
3801
Geoff Lang496c02d2016-10-20 11:38:11 -07003802bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003803 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003804 GLenum pname,
3805 GLsizei *length,
3806 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003807{
Geoff Lang496c02d2016-10-20 11:38:11 -07003808 if (length)
3809 {
3810 *length = 0;
3811 }
3812
3813 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3814 {
Jamie Madill610640f2018-11-21 17:28:41 -05003815 context->validationError(
3816 GL_INVALID_OPERATION,
3817 "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003818 return false;
3819 }
3820
Corentin Walleze4477002017-12-01 14:39:58 -05003821 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003822 {
Jamie Madill610640f2018-11-21 17:28:41 -05003823 context->validationError(GL_INVALID_ENUM, "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003824 return false;
3825 }
3826
Geoff Lang496c02d2016-10-20 11:38:11 -07003827 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003828 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003829 case GL_BUFFER_MAP_POINTER:
3830 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003831
Geoff Lang496c02d2016-10-20 11:38:11 -07003832 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003833 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003834 return false;
3835 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003836
3837 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3838 // target bound to zero generate an INVALID_OPERATION error."
3839 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003840 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003841 {
Jamie Madill610640f2018-11-21 17:28:41 -05003842 context->validationError(GL_INVALID_OPERATION,
3843 "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003844 return false;
3845 }
3846
Geoff Lang496c02d2016-10-20 11:38:11 -07003847 if (length)
3848 {
3849 *length = 1;
3850 }
3851
Olli Etuaho4f667482016-03-30 15:56:35 +03003852 return true;
3853}
3854
Corentin Wallez336129f2017-10-17 15:55:40 -04003855bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003856{
Corentin Walleze4477002017-12-01 14:39:58 -05003857 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003858 {
Jamie Madille0472f32018-11-27 16:32:45 -05003859 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003860 return false;
3861 }
3862
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003863 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003864
3865 if (buffer == nullptr || !buffer->isMapped())
3866 {
Jamie Madill610640f2018-11-21 17:28:41 -05003867 context->validationError(GL_INVALID_OPERATION, "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003868 return false;
3869 }
3870
3871 return true;
3872}
3873
3874bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003875 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003876 GLintptr offset,
3877 GLsizeiptr length,
3878 GLbitfield access)
3879{
Corentin Walleze4477002017-12-01 14:39:58 -05003880 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003881 {
Jamie Madille0472f32018-11-27 16:32:45 -05003882 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003883 return false;
3884 }
3885
Brandon Jones6cad5662017-06-14 13:25:13 -07003886 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003887 {
Jamie Madille0472f32018-11-27 16:32:45 -05003888 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003889 return false;
3890 }
3891
3892 if (length < 0)
3893 {
Jamie Madille0472f32018-11-27 16:32:45 -05003894 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003895 return false;
3896 }
3897
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003898 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003899
3900 if (!buffer)
3901 {
Jamie Madill610640f2018-11-21 17:28:41 -05003902 context->validationError(GL_INVALID_OPERATION, "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003903 return false;
3904 }
3905
3906 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003907 CheckedNumeric<size_t> checkedOffset(offset);
3908 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003909
Jamie Madille2e406c2016-06-02 13:04:10 -04003910 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003911 {
Jamie Madill610640f2018-11-21 17:28:41 -05003912 context->validationError(GL_INVALID_VALUE,
3913 "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003914 return false;
3915 }
3916
3917 // Check for invalid bits in the mask
3918 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3919 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3920 GL_MAP_UNSYNCHRONIZED_BIT;
3921
3922 if (access & ~(allAccessBits))
3923 {
Jamie Madill610640f2018-11-21 17:28:41 -05003924 context->validationError(GL_INVALID_VALUE, "Invalid access bits");
Olli Etuaho4f667482016-03-30 15:56:35 +03003925 return false;
3926 }
3927
3928 if (length == 0)
3929 {
Jamie Madill610640f2018-11-21 17:28:41 -05003930 context->validationError(GL_INVALID_OPERATION, "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003931 return false;
3932 }
3933
3934 if (buffer->isMapped())
3935 {
Jamie Madill610640f2018-11-21 17:28:41 -05003936 context->validationError(GL_INVALID_OPERATION, "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003937 return false;
3938 }
3939
3940 // Check for invalid bit combinations
3941 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3942 {
Jamie Madill610640f2018-11-21 17:28:41 -05003943 context->validationError(GL_INVALID_OPERATION,
3944 "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003945 return false;
3946 }
3947
3948 GLbitfield writeOnlyBits =
3949 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3950
3951 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3952 {
Jamie Madill610640f2018-11-21 17:28:41 -05003953 context->validationError(GL_INVALID_OPERATION,
3954 "Invalid access bits when mapping buffer for reading");
Olli Etuaho4f667482016-03-30 15:56:35 +03003955 return false;
3956 }
3957
3958 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3959 {
Jamie Madill610640f2018-11-21 17:28:41 -05003960 context->validationError(
3961 GL_INVALID_OPERATION,
3962 "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003963 return false;
3964 }
Geoff Lang79f71042017-08-14 16:43:43 -04003965
3966 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003967}
3968
3969bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003970 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003971 GLintptr offset,
3972 GLsizeiptr length)
3973{
Brandon Jones6cad5662017-06-14 13:25:13 -07003974 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003975 {
Jamie Madille0472f32018-11-27 16:32:45 -05003976 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003977 return false;
3978 }
3979
3980 if (length < 0)
3981 {
Jamie Madille0472f32018-11-27 16:32:45 -05003982 context->validationError(GL_INVALID_VALUE, kNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003983 return false;
3984 }
3985
Corentin Walleze4477002017-12-01 14:39:58 -05003986 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003987 {
Jamie Madille0472f32018-11-27 16:32:45 -05003988 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003989 return false;
3990 }
3991
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003992 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003993
3994 if (buffer == nullptr)
3995 {
Jamie Madill610640f2018-11-21 17:28:41 -05003996 context->validationError(GL_INVALID_OPERATION, "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003997 return false;
3998 }
3999
4000 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
4001 {
Jamie Madill610640f2018-11-21 17:28:41 -05004002 context->validationError(GL_INVALID_OPERATION,
4003 "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004004 return false;
4005 }
4006
4007 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04004008 CheckedNumeric<size_t> checkedOffset(offset);
4009 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03004010
Jamie Madille2e406c2016-06-02 13:04:10 -04004011 if (!checkedSize.IsValid() ||
4012 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03004013 {
Jamie Madill610640f2018-11-21 17:28:41 -05004014 context->validationError(GL_INVALID_VALUE,
4015 "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004016 return false;
4017 }
4018
4019 return true;
4020}
4021
Olli Etuaho41997e72016-03-10 13:38:39 +02004022bool ValidateGenOrDelete(Context *context, GLint n)
4023{
4024 if (n < 0)
4025 {
Jamie Madille0472f32018-11-27 16:32:45 -05004026 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004027 return false;
4028 }
4029 return true;
4030}
4031
Jamie Madill5b772312018-03-08 20:28:32 -05004032bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004033{
4034 if (!context->getExtensions().robustClientMemory)
4035 {
Jamie Madill610640f2018-11-21 17:28:41 -05004036 context->validationError(GL_INVALID_OPERATION,
4037 "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004038 return false;
4039 }
4040
4041 if (bufSize < 0)
4042 {
Jamie Madille0472f32018-11-27 16:32:45 -05004043 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004044 return false;
4045 }
4046
4047 return true;
4048}
4049
Jamie Madill5b772312018-03-08 20:28:32 -05004050bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004051{
4052 if (bufSize < numParams)
4053 {
Jamie Madill610640f2018-11-21 17:28:41 -05004054 context->validationError(GL_INVALID_OPERATION,
4055 "More parameters are required than were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004056 return false;
4057 }
4058
4059 return true;
4060}
4061
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004062bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004063 GLenum target,
4064 GLenum attachment,
4065 GLenum pname,
4066 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004067{
Geoff Lange8afa902017-09-27 15:00:43 -04004068 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004069 {
Jamie Madille0472f32018-11-27 16:32:45 -05004070 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004071 return false;
4072 }
4073
4074 int clientVersion = context->getClientMajorVersion();
4075
4076 switch (pname)
4077 {
4078 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4079 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4080 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4081 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4082 break;
4083
Martin Radeve5285d22017-07-14 16:23:53 +03004084 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4085 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4086 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4087 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4088 if (clientVersion < 3 || !context->getExtensions().multiview)
4089 {
Jamie Madille0472f32018-11-27 16:32:45 -05004090 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03004091 return false;
4092 }
4093 break;
4094
Geoff Langff5b2d52016-09-07 11:32:23 -04004095 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4096 if (clientVersion < 3 && !context->getExtensions().sRGB)
4097 {
Jamie Madille0472f32018-11-27 16:32:45 -05004098 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004099 return false;
4100 }
4101 break;
4102
4103 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4104 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4105 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4106 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4107 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4108 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4109 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4110 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4111 if (clientVersion < 3)
4112 {
Jamie Madille0472f32018-11-27 16:32:45 -05004113 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004114 return false;
4115 }
4116 break;
4117
Jiawei Shaoa8802472018-05-28 11:17:47 +08004118 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4119 if (!context->getExtensions().geometryShader)
4120 {
Jamie Madille0472f32018-11-27 16:32:45 -05004121 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08004122 return false;
4123 }
4124 break;
4125
Geoff Langff5b2d52016-09-07 11:32:23 -04004126 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004127 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04004128 return false;
4129 }
4130
4131 // Determine if the attachment is a valid enum
4132 switch (attachment)
4133 {
4134 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004135 case GL_DEPTH:
4136 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004137 if (clientVersion < 3)
4138 {
Jamie Madille0472f32018-11-27 16:32:45 -05004139 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004140 return false;
4141 }
4142 break;
4143
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004144 case GL_DEPTH_STENCIL_ATTACHMENT:
4145 if (clientVersion < 3 && !context->isWebGL1())
4146 {
Jamie Madille0472f32018-11-27 16:32:45 -05004147 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004148 return false;
4149 }
4150 break;
4151
Geoff Langfa125c92017-10-24 13:01:46 -04004152 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004153 case GL_DEPTH_ATTACHMENT:
4154 case GL_STENCIL_ATTACHMENT:
4155 break;
4156
4157 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004158 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4159 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004160 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4161 {
Jamie Madille0472f32018-11-27 16:32:45 -05004162 context->validationError(GL_INVALID_ENUM, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004163 return false;
4164 }
4165 break;
4166 }
4167
4168 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4169 ASSERT(framebuffer);
4170
4171 if (framebuffer->id() == 0)
4172 {
4173 if (clientVersion < 3)
4174 {
Jamie Madille0472f32018-11-27 16:32:45 -05004175 context->validationError(GL_INVALID_OPERATION, kDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004176 return false;
4177 }
4178
4179 switch (attachment)
4180 {
4181 case GL_BACK:
4182 case GL_DEPTH:
4183 case GL_STENCIL:
4184 break;
4185
4186 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004187 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004188 return false;
4189 }
4190 }
4191 else
4192 {
4193 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4194 {
4195 // Valid attachment query
4196 }
4197 else
4198 {
4199 switch (attachment)
4200 {
4201 case GL_DEPTH_ATTACHMENT:
4202 case GL_STENCIL_ATTACHMENT:
4203 break;
4204
4205 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004206 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004207 {
Jamie Madille0472f32018-11-27 16:32:45 -05004208 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004209 return false;
4210 }
4211 break;
4212
4213 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004214 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004215 return false;
4216 }
4217 }
4218 }
4219
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004220 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004221 if (attachmentObject)
4222 {
4223 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4224 attachmentObject->type() == GL_TEXTURE ||
4225 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4226
4227 switch (pname)
4228 {
4229 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4230 if (attachmentObject->type() != GL_RENDERBUFFER &&
4231 attachmentObject->type() != GL_TEXTURE)
4232 {
Jamie Madille0472f32018-11-27 16:32:45 -05004233 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004234 return false;
4235 }
4236 break;
4237
4238 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4239 if (attachmentObject->type() != GL_TEXTURE)
4240 {
Jamie Madille0472f32018-11-27 16:32:45 -05004241 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004242 return false;
4243 }
4244 break;
4245
4246 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4247 if (attachmentObject->type() != GL_TEXTURE)
4248 {
Jamie Madille0472f32018-11-27 16:32:45 -05004249 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004250 return false;
4251 }
4252 break;
4253
4254 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4255 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4256 {
Jamie Madille0472f32018-11-27 16:32:45 -05004257 context->validationError(GL_INVALID_OPERATION, kInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004258 return false;
4259 }
4260 break;
4261
4262 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4263 if (attachmentObject->type() != GL_TEXTURE)
4264 {
Jamie Madille0472f32018-11-27 16:32:45 -05004265 context->validationError(GL_INVALID_ENUM, kFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004266 return false;
4267 }
4268 break;
4269
4270 default:
4271 break;
4272 }
4273 }
4274 else
4275 {
4276 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4277 // is NONE, then querying any other pname will generate INVALID_ENUM.
4278
4279 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4280 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4281 // INVALID_OPERATION for all other pnames
4282
4283 switch (pname)
4284 {
4285 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4286 break;
4287
4288 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4289 if (clientVersion < 3)
4290 {
Jamie Madill610640f2018-11-21 17:28:41 -05004291 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004292 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004293 return false;
4294 }
4295 break;
4296
4297 default:
4298 if (clientVersion < 3)
4299 {
Jamie Madill610640f2018-11-21 17:28:41 -05004300 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05004301 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004302 return false;
4303 }
4304 else
4305 {
Jamie Madill610640f2018-11-21 17:28:41 -05004306 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05004307 kInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004308 return false;
4309 }
4310 }
4311 }
4312
Martin Radeve5285d22017-07-14 16:23:53 +03004313 if (numParams)
4314 {
4315 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4316 {
4317 // Only when the viewport offsets are queried we can have a varying number of output
4318 // parameters.
4319 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4320 *numParams = numViews * 2;
4321 }
4322 else
4323 {
4324 // For all other queries we can have only one output parameter.
4325 *numParams = 1;
4326 }
4327 }
4328
Geoff Langff5b2d52016-09-07 11:32:23 -04004329 return true;
4330}
4331
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004332bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004333 GLenum target,
4334 GLenum attachment,
4335 GLenum pname,
4336 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004337 GLsizei *length,
4338 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004339{
4340 if (!ValidateRobustEntryPoint(context, bufSize))
4341 {
4342 return false;
4343 }
4344
Brandon Jonesd1049182018-03-28 10:02:20 -07004345 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004346 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004347 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004348 {
4349 return false;
4350 }
4351
Brandon Jonesd1049182018-03-28 10:02:20 -07004352 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004353 {
4354 return false;
4355 }
4356
Brandon Jonesd1049182018-03-28 10:02:20 -07004357 SetRobustLengthParam(length, numParams);
4358
Geoff Langff5b2d52016-09-07 11:32:23 -04004359 return true;
4360}
4361
Jamie Madill5b772312018-03-08 20:28:32 -05004362bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004363 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004364 GLenum pname,
4365 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004366 GLsizei *length,
4367 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004368{
4369 if (!ValidateRobustEntryPoint(context, bufSize))
4370 {
4371 return false;
4372 }
4373
Brandon Jonesd1049182018-03-28 10:02:20 -07004374 GLsizei numParams = 0;
4375
4376 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004377 {
4378 return false;
4379 }
4380
Brandon Jonesd1049182018-03-28 10:02:20 -07004381 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004382 {
4383 return false;
4384 }
4385
Brandon Jonesd1049182018-03-28 10:02:20 -07004386 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004387 return true;
4388}
4389
Jamie Madill5b772312018-03-08 20:28:32 -05004390bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004391 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004392 GLenum pname,
4393 GLsizei bufSize,
4394 GLsizei *length,
4395 GLint64 *params)
4396{
Brandon Jonesd1049182018-03-28 10:02:20 -07004397 GLsizei numParams = 0;
4398
Geoff Langebebe1c2016-10-14 12:01:31 -04004399 if (!ValidateRobustEntryPoint(context, bufSize))
4400 {
4401 return false;
4402 }
4403
Brandon Jonesd1049182018-03-28 10:02:20 -07004404 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004405 {
4406 return false;
4407 }
4408
Brandon Jonesd1049182018-03-28 10:02:20 -07004409 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004410 {
4411 return false;
4412 }
4413
Brandon Jonesd1049182018-03-28 10:02:20 -07004414 SetRobustLengthParam(length, numParams);
4415
Geoff Langff5b2d52016-09-07 11:32:23 -04004416 return true;
4417}
4418
Jamie Madill5b772312018-03-08 20:28:32 -05004419bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004420{
4421 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004422 if (numParams)
4423 {
4424 *numParams = 1;
4425 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004426
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004427 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4428 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4429 ? GetValidProgramNoResolve(context, program)
4430 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004431 if (!programObject)
4432 {
4433 return false;
4434 }
4435
4436 switch (pname)
4437 {
4438 case GL_DELETE_STATUS:
4439 case GL_LINK_STATUS:
4440 case GL_VALIDATE_STATUS:
4441 case GL_INFO_LOG_LENGTH:
4442 case GL_ATTACHED_SHADERS:
4443 case GL_ACTIVE_ATTRIBUTES:
4444 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4445 case GL_ACTIVE_UNIFORMS:
4446 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4447 break;
4448
4449 case GL_PROGRAM_BINARY_LENGTH:
4450 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4451 {
Jamie Madill610640f2018-11-21 17:28:41 -05004452 context->validationError(GL_INVALID_ENUM,
4453 "Querying GL_PROGRAM_BINARY_LENGTH "
4454 "requires GL_OES_get_program_binary or "
4455 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004456 return false;
4457 }
4458 break;
4459
4460 case GL_ACTIVE_UNIFORM_BLOCKS:
4461 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4462 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4463 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4464 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4465 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4466 if (context->getClientMajorVersion() < 3)
4467 {
Jamie Madille0472f32018-11-27 16:32:45 -05004468 context->validationError(GL_INVALID_ENUM, kES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004469 return false;
4470 }
4471 break;
4472
Yunchao He61afff12017-03-14 15:34:03 +08004473 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004474 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004475 if (context->getClientVersion() < Version(3, 1))
4476 {
Jamie Madille0472f32018-11-27 16:32:45 -05004477 context->validationError(GL_INVALID_ENUM, kES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004478 return false;
4479 }
4480 break;
4481
Jiawei Shao6ae51612018-02-23 14:03:25 +08004482 case GL_COMPUTE_WORK_GROUP_SIZE:
4483 if (context->getClientVersion() < Version(3, 1))
4484 {
Jamie Madille0472f32018-11-27 16:32:45 -05004485 context->validationError(GL_INVALID_ENUM, kES31Required);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004486 return false;
4487 }
4488
4489 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4490 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4491 // program which has not been linked successfully, or which does not contain objects to
4492 // form a compute shader.
4493 if (!programObject->isLinked())
4494 {
Jamie Madille0472f32018-11-27 16:32:45 -05004495 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004496 return false;
4497 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004498 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004499 {
Jamie Madille0472f32018-11-27 16:32:45 -05004500 context->validationError(GL_INVALID_OPERATION, kNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004501 return false;
4502 }
4503 break;
4504
Jiawei Shao447bfac2018-03-14 14:23:40 +08004505 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4506 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4507 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4508 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4509 if (!context->getExtensions().geometryShader)
4510 {
Jamie Madille0472f32018-11-27 16:32:45 -05004511 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004512 return false;
4513 }
4514
4515 // [EXT_geometry_shader] Chapter 7.12
4516 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4517 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4518 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4519 // successfully, or which does not contain objects to form a geometry shader.
4520 if (!programObject->isLinked())
4521 {
Jamie Madille0472f32018-11-27 16:32:45 -05004522 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004523 return false;
4524 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004525 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004526 {
Jamie Madille0472f32018-11-27 16:32:45 -05004527 context->validationError(GL_INVALID_OPERATION, kNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004528 return false;
4529 }
4530 break;
4531
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004532 case GL_COMPLETION_STATUS_KHR:
4533 if (!context->getExtensions().parallelShaderCompile)
4534 {
Jamie Madille0472f32018-11-27 16:32:45 -05004535 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004536 return false;
4537 }
4538 break;
4539
Geoff Langff5b2d52016-09-07 11:32:23 -04004540 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004541 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004542 return false;
4543 }
4544
4545 return true;
4546}
4547
4548bool ValidateGetProgramivRobustANGLE(Context *context,
4549 GLuint program,
4550 GLenum pname,
4551 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004552 GLsizei *length,
4553 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004554{
4555 if (!ValidateRobustEntryPoint(context, bufSize))
4556 {
4557 return false;
4558 }
4559
Brandon Jonesd1049182018-03-28 10:02:20 -07004560 GLsizei numParams = 0;
4561
4562 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004563 {
4564 return false;
4565 }
4566
Brandon Jonesd1049182018-03-28 10:02:20 -07004567 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004568 {
4569 return false;
4570 }
4571
Brandon Jonesd1049182018-03-28 10:02:20 -07004572 SetRobustLengthParam(length, numParams);
4573
Geoff Langff5b2d52016-09-07 11:32:23 -04004574 return true;
4575}
4576
Geoff Lang740d9022016-10-07 11:20:52 -04004577bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4578 GLenum target,
4579 GLenum pname,
4580 GLsizei bufSize,
4581 GLsizei *length,
4582 GLint *params)
4583{
4584 if (!ValidateRobustEntryPoint(context, bufSize))
4585 {
4586 return false;
4587 }
4588
Brandon Jonesd1049182018-03-28 10:02:20 -07004589 GLsizei numParams = 0;
4590
4591 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004592 {
4593 return false;
4594 }
4595
Brandon Jonesd1049182018-03-28 10:02:20 -07004596 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004597 {
4598 return false;
4599 }
4600
Brandon Jonesd1049182018-03-28 10:02:20 -07004601 SetRobustLengthParam(length, numParams);
4602
Geoff Lang740d9022016-10-07 11:20:52 -04004603 return true;
4604}
4605
Geoff Langd7d0ed32016-10-07 11:33:51 -04004606bool ValidateGetShaderivRobustANGLE(Context *context,
4607 GLuint shader,
4608 GLenum pname,
4609 GLsizei bufSize,
4610 GLsizei *length,
4611 GLint *params)
4612{
4613 if (!ValidateRobustEntryPoint(context, bufSize))
4614 {
4615 return false;
4616 }
4617
Brandon Jonesd1049182018-03-28 10:02:20 -07004618 GLsizei numParams = 0;
4619
4620 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004621 {
4622 return false;
4623 }
4624
Brandon Jonesd1049182018-03-28 10:02:20 -07004625 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004626 {
4627 return false;
4628 }
4629
Brandon Jonesd1049182018-03-28 10:02:20 -07004630 SetRobustLengthParam(length, numParams);
4631
Geoff Langd7d0ed32016-10-07 11:33:51 -04004632 return true;
4633}
4634
Geoff Langc1984ed2016-10-07 12:41:00 -04004635bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004636 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004637 GLenum pname,
4638 GLsizei bufSize,
4639 GLsizei *length,
4640 GLfloat *params)
4641{
4642 if (!ValidateRobustEntryPoint(context, bufSize))
4643 {
4644 return false;
4645 }
4646
Brandon Jonesd1049182018-03-28 10:02:20 -07004647 GLsizei numParams = 0;
4648
4649 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004650 {
4651 return false;
4652 }
4653
Brandon Jonesd1049182018-03-28 10:02:20 -07004654 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004655 {
4656 return false;
4657 }
4658
Brandon Jonesd1049182018-03-28 10:02:20 -07004659 SetRobustLengthParam(length, numParams);
4660
Geoff Langc1984ed2016-10-07 12:41:00 -04004661 return true;
4662}
4663
Geoff Langc1984ed2016-10-07 12:41:00 -04004664bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004665 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004666 GLenum pname,
4667 GLsizei bufSize,
4668 GLsizei *length,
4669 GLint *params)
4670{
Brandon Jonesd1049182018-03-28 10:02:20 -07004671
Geoff Langc1984ed2016-10-07 12:41:00 -04004672 if (!ValidateRobustEntryPoint(context, bufSize))
4673 {
4674 return false;
4675 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004676 GLsizei numParams = 0;
4677 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004678 {
4679 return false;
4680 }
4681
Brandon Jonesd1049182018-03-28 10:02:20 -07004682 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004683 {
4684 return false;
4685 }
4686
Brandon Jonesd1049182018-03-28 10:02:20 -07004687 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004688 return true;
4689}
4690
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004691bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4692 TextureType target,
4693 GLenum pname,
4694 GLsizei bufSize,
4695 GLsizei *length,
4696 GLint *params)
4697{
4698 UNIMPLEMENTED();
4699 return false;
4700}
4701
4702bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4703 TextureType target,
4704 GLenum pname,
4705 GLsizei bufSize,
4706 GLsizei *length,
4707 GLuint *params)
4708{
4709 UNIMPLEMENTED();
4710 return false;
4711}
4712
Geoff Langc1984ed2016-10-07 12:41:00 -04004713bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004714 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004715 GLenum pname,
4716 GLsizei bufSize,
4717 const GLfloat *params)
4718{
4719 if (!ValidateRobustEntryPoint(context, bufSize))
4720 {
4721 return false;
4722 }
4723
Till Rathmannb8543632018-10-02 19:46:14 +02004724 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004725}
4726
Geoff Langc1984ed2016-10-07 12:41:00 -04004727bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004728 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004729 GLenum pname,
4730 GLsizei bufSize,
4731 const GLint *params)
4732{
4733 if (!ValidateRobustEntryPoint(context, bufSize))
4734 {
4735 return false;
4736 }
4737
Till Rathmannb8543632018-10-02 19:46:14 +02004738 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004739}
4740
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004741bool ValidateTexParameterIivRobustANGLE(Context *context,
4742 TextureType target,
4743 GLenum pname,
4744 GLsizei bufSize,
4745 const GLint *params)
4746{
4747 UNIMPLEMENTED();
4748 return false;
4749}
4750
4751bool ValidateTexParameterIuivRobustANGLE(Context *context,
4752 TextureType target,
4753 GLenum pname,
4754 GLsizei bufSize,
4755 const GLuint *params)
4756{
4757 UNIMPLEMENTED();
4758 return false;
4759}
4760
Geoff Langc1984ed2016-10-07 12:41:00 -04004761bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4762 GLuint sampler,
4763 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004764 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004765 GLsizei *length,
4766 GLfloat *params)
4767{
4768 if (!ValidateRobustEntryPoint(context, bufSize))
4769 {
4770 return false;
4771 }
4772
Brandon Jonesd1049182018-03-28 10:02:20 -07004773 GLsizei numParams = 0;
4774
4775 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004776 {
4777 return false;
4778 }
4779
Brandon Jonesd1049182018-03-28 10:02:20 -07004780 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004781 {
4782 return false;
4783 }
4784
Brandon Jonesd1049182018-03-28 10:02:20 -07004785 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004786 return true;
4787}
4788
Geoff Langc1984ed2016-10-07 12:41:00 -04004789bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4790 GLuint sampler,
4791 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004792 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004793 GLsizei *length,
4794 GLint *params)
4795{
4796 if (!ValidateRobustEntryPoint(context, bufSize))
4797 {
4798 return false;
4799 }
4800
Brandon Jonesd1049182018-03-28 10:02:20 -07004801 GLsizei numParams = 0;
4802
4803 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004804 {
4805 return false;
4806 }
4807
Brandon Jonesd1049182018-03-28 10:02:20 -07004808 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004809 {
4810 return false;
4811 }
4812
Brandon Jonesd1049182018-03-28 10:02:20 -07004813 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004814 return true;
4815}
4816
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004817bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4818 GLuint sampler,
4819 GLenum pname,
4820 GLsizei bufSize,
4821 GLsizei *length,
4822 GLint *params)
4823{
4824 UNIMPLEMENTED();
4825 return false;
4826}
4827
4828bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4829 GLuint sampler,
4830 GLenum pname,
4831 GLsizei bufSize,
4832 GLsizei *length,
4833 GLuint *params)
4834{
4835 UNIMPLEMENTED();
4836 return false;
4837}
4838
Geoff Langc1984ed2016-10-07 12:41:00 -04004839bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4840 GLuint sampler,
4841 GLenum pname,
4842 GLsizei bufSize,
4843 const GLfloat *params)
4844{
4845 if (!ValidateRobustEntryPoint(context, bufSize))
4846 {
4847 return false;
4848 }
4849
Till Rathmannb8543632018-10-02 19:46:14 +02004850 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004851}
4852
Geoff Langc1984ed2016-10-07 12:41:00 -04004853bool ValidateSamplerParameterivRobustANGLE(Context *context,
4854 GLuint sampler,
4855 GLenum pname,
4856 GLsizei bufSize,
4857 const GLint *params)
4858{
4859 if (!ValidateRobustEntryPoint(context, bufSize))
4860 {
4861 return false;
4862 }
4863
Till Rathmannb8543632018-10-02 19:46:14 +02004864 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004865}
4866
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004867bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4868 GLuint sampler,
4869 GLenum pname,
4870 GLsizei bufSize,
4871 const GLint *param)
4872{
4873 UNIMPLEMENTED();
4874 return false;
4875}
4876
4877bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4878 GLuint sampler,
4879 GLenum pname,
4880 GLsizei bufSize,
4881 const GLuint *param)
4882{
4883 UNIMPLEMENTED();
4884 return false;
4885}
4886
Geoff Lang0b031062016-10-13 14:30:04 -04004887bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4888 GLuint index,
4889 GLenum pname,
4890 GLsizei bufSize,
4891 GLsizei *length,
4892 GLfloat *params)
4893{
4894 if (!ValidateRobustEntryPoint(context, bufSize))
4895 {
4896 return false;
4897 }
4898
Brandon Jonesd1049182018-03-28 10:02:20 -07004899 GLsizei writeLength = 0;
4900
4901 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004902 {
4903 return false;
4904 }
4905
Brandon Jonesd1049182018-03-28 10:02:20 -07004906 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004907 {
4908 return false;
4909 }
4910
Brandon Jonesd1049182018-03-28 10:02:20 -07004911 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004912 return true;
4913}
4914
Geoff Lang0b031062016-10-13 14:30:04 -04004915bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4916 GLuint index,
4917 GLenum pname,
4918 GLsizei bufSize,
4919 GLsizei *length,
4920 GLint *params)
4921{
4922 if (!ValidateRobustEntryPoint(context, bufSize))
4923 {
4924 return false;
4925 }
4926
Brandon Jonesd1049182018-03-28 10:02:20 -07004927 GLsizei writeLength = 0;
4928
4929 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004930 {
4931 return false;
4932 }
4933
Brandon Jonesd1049182018-03-28 10:02:20 -07004934 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004935 {
4936 return false;
4937 }
4938
Brandon Jonesd1049182018-03-28 10:02:20 -07004939 SetRobustLengthParam(length, writeLength);
4940
Geoff Lang0b031062016-10-13 14:30:04 -04004941 return true;
4942}
4943
Geoff Lang0b031062016-10-13 14:30:04 -04004944bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4945 GLuint index,
4946 GLenum pname,
4947 GLsizei bufSize,
4948 GLsizei *length,
4949 void **pointer)
4950{
4951 if (!ValidateRobustEntryPoint(context, bufSize))
4952 {
4953 return false;
4954 }
4955
Brandon Jonesd1049182018-03-28 10:02:20 -07004956 GLsizei writeLength = 0;
4957
4958 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004959 {
4960 return false;
4961 }
4962
Brandon Jonesd1049182018-03-28 10:02:20 -07004963 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004964 {
4965 return false;
4966 }
4967
Brandon Jonesd1049182018-03-28 10:02:20 -07004968 SetRobustLengthParam(length, writeLength);
4969
Geoff Lang0b031062016-10-13 14:30:04 -04004970 return true;
4971}
4972
Geoff Lang0b031062016-10-13 14:30:04 -04004973bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4974 GLuint index,
4975 GLenum pname,
4976 GLsizei bufSize,
4977 GLsizei *length,
4978 GLint *params)
4979{
4980 if (!ValidateRobustEntryPoint(context, bufSize))
4981 {
4982 return false;
4983 }
4984
Brandon Jonesd1049182018-03-28 10:02:20 -07004985 GLsizei writeLength = 0;
4986
4987 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004988 {
4989 return false;
4990 }
4991
Brandon Jonesd1049182018-03-28 10:02:20 -07004992 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004993 {
4994 return false;
4995 }
4996
Brandon Jonesd1049182018-03-28 10:02:20 -07004997 SetRobustLengthParam(length, writeLength);
4998
Geoff Lang0b031062016-10-13 14:30:04 -04004999 return true;
5000}
5001
Geoff Lang0b031062016-10-13 14:30:04 -04005002bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
5003 GLuint index,
5004 GLenum pname,
5005 GLsizei bufSize,
5006 GLsizei *length,
5007 GLuint *params)
5008{
5009 if (!ValidateRobustEntryPoint(context, bufSize))
5010 {
5011 return false;
5012 }
5013
Brandon Jonesd1049182018-03-28 10:02:20 -07005014 GLsizei writeLength = 0;
5015
5016 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04005017 {
5018 return false;
5019 }
5020
Brandon Jonesd1049182018-03-28 10:02:20 -07005021 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04005022 {
5023 return false;
5024 }
5025
Brandon Jonesd1049182018-03-28 10:02:20 -07005026 SetRobustLengthParam(length, writeLength);
5027
Geoff Lang0b031062016-10-13 14:30:04 -04005028 return true;
5029}
5030
Geoff Lang6899b872016-10-14 11:30:13 -04005031bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5032 GLuint program,
5033 GLuint uniformBlockIndex,
5034 GLenum pname,
5035 GLsizei bufSize,
5036 GLsizei *length,
5037 GLint *params)
5038{
5039 if (!ValidateRobustEntryPoint(context, bufSize))
5040 {
5041 return false;
5042 }
5043
Brandon Jonesd1049182018-03-28 10:02:20 -07005044 GLsizei writeLength = 0;
5045
5046 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5047 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005048 {
5049 return false;
5050 }
5051
Brandon Jonesd1049182018-03-28 10:02:20 -07005052 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005053 {
5054 return false;
5055 }
5056
Brandon Jonesd1049182018-03-28 10:02:20 -07005057 SetRobustLengthParam(length, writeLength);
5058
Geoff Lang6899b872016-10-14 11:30:13 -04005059 return true;
5060}
5061
Brandon Jones416aaf92018-04-10 08:10:16 -07005062bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005063 GLenum target,
5064 GLenum internalformat,
5065 GLenum pname,
5066 GLsizei bufSize,
5067 GLsizei *length,
5068 GLint *params)
5069{
5070 if (!ValidateRobustEntryPoint(context, bufSize))
5071 {
5072 return false;
5073 }
5074
Brandon Jonesd1049182018-03-28 10:02:20 -07005075 GLsizei numParams = 0;
5076
5077 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5078 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005079 {
5080 return false;
5081 }
5082
Brandon Jonesd1049182018-03-28 10:02:20 -07005083 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005084 {
5085 return false;
5086 }
5087
Brandon Jonesd1049182018-03-28 10:02:20 -07005088 SetRobustLengthParam(length, numParams);
5089
Geoff Lang0a9661f2016-10-20 10:59:20 -07005090 return true;
5091}
5092
Jamie Madill5b772312018-03-08 20:28:32 -05005093bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005094 GLuint attribIndex,
5095 GLint size,
5096 GLenum type,
5097 GLboolean pureInteger)
5098{
5099 const Caps &caps = context->getCaps();
5100 if (attribIndex >= caps.maxVertexAttributes)
5101 {
Jamie Madille0472f32018-11-27 16:32:45 -05005102 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005103 return false;
5104 }
5105
5106 if (size < 1 || size > 4)
5107 {
Jamie Madille0472f32018-11-27 16:32:45 -05005108 context->validationError(GL_INVALID_VALUE, kInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005109 return false;
Shao80957d92017-02-20 21:25:59 +08005110 }
5111
5112 switch (type)
5113 {
5114 case GL_BYTE:
5115 case GL_UNSIGNED_BYTE:
5116 case GL_SHORT:
5117 case GL_UNSIGNED_SHORT:
5118 break;
5119
5120 case GL_INT:
5121 case GL_UNSIGNED_INT:
5122 if (context->getClientMajorVersion() < 3)
5123 {
Jamie Madill610640f2018-11-21 17:28:41 -05005124 context->validationError(GL_INVALID_ENUM,
5125 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005126 return false;
5127 }
5128 break;
5129
5130 case GL_FIXED:
5131 case GL_FLOAT:
5132 if (pureInteger)
5133 {
Jamie Madille0472f32018-11-27 16:32:45 -05005134 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005135 return false;
5136 }
5137 break;
5138
5139 case GL_HALF_FLOAT:
5140 if (context->getClientMajorVersion() < 3)
5141 {
Jamie Madill610640f2018-11-21 17:28:41 -05005142 context->validationError(GL_INVALID_ENUM,
5143 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005144 return false;
5145 }
5146 if (pureInteger)
5147 {
Jamie Madille0472f32018-11-27 16:32:45 -05005148 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005149 return false;
5150 }
5151 break;
5152
5153 case GL_INT_2_10_10_10_REV:
5154 case GL_UNSIGNED_INT_2_10_10_10_REV:
5155 if (context->getClientMajorVersion() < 3)
5156 {
Jamie Madill610640f2018-11-21 17:28:41 -05005157 context->validationError(GL_INVALID_ENUM,
5158 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005159 return false;
5160 }
5161 if (pureInteger)
5162 {
Jamie Madille0472f32018-11-27 16:32:45 -05005163 context->validationError(GL_INVALID_ENUM, kInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005164 return false;
5165 }
5166 if (size != 4)
5167 {
Jamie Madill610640f2018-11-21 17:28:41 -05005168 context->validationError(GL_INVALID_OPERATION,
5169 "Type is INT_2_10_10_10_REV or "
5170 "UNSIGNED_INT_2_10_10_10_REV and "
5171 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005172 return false;
5173 }
5174 break;
5175
5176 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005177 context->validationError(GL_INVALID_ENUM, kInvalidType);
Shao80957d92017-02-20 21:25:59 +08005178 return false;
5179 }
5180
5181 return true;
5182}
5183
Geoff Lang76e65652017-03-27 14:58:02 -04005184// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5185// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5186// specified clear value and the type of a buffer that is being cleared generates an
5187// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005188bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005189 GLint drawbuffer,
5190 const GLenum *validComponentTypes,
5191 size_t validComponentTypeCount)
5192{
5193 const FramebufferAttachment *attachment =
5194 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5195 if (attachment)
5196 {
5197 GLenum componentType = attachment->getFormat().info->componentType;
5198 const GLenum *end = validComponentTypes + validComponentTypeCount;
5199 if (std::find(validComponentTypes, end, componentType) == end)
5200 {
Jamie Madill610640f2018-11-21 17:28:41 -05005201 context->validationError(
5202 GL_INVALID_OPERATION,
5203 "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005204 return false;
5205 }
5206 }
5207
5208 return true;
5209}
5210
Jamie Madill5b772312018-03-08 20:28:32 -05005211bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005212{
5213 if (!ValidateRobustEntryPoint(context, dataSize))
5214 {
5215 return false;
5216 }
5217
Jamie Madill43da7c42018-08-01 11:34:49 -04005218 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005219 if (pixelUnpackBuffer == nullptr)
5220 {
5221 if (dataSize < imageSize)
5222 {
Jamie Madill610640f2018-11-21 17:28:41 -05005223 context->validationError(GL_INVALID_OPERATION, "dataSize is too small");
Corentin Wallezb2931602017-04-11 15:58:57 -04005224 }
5225 }
5226 return true;
5227}
5228
Jamie Madill5b772312018-03-08 20:28:32 -05005229bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005230 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005231 GLenum pname,
5232 bool pointerVersion,
5233 GLsizei *numParams)
5234{
5235 if (numParams)
5236 {
5237 *numParams = 0;
5238 }
5239
Corentin Walleze4477002017-12-01 14:39:58 -05005240 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005241 {
Jamie Madille0472f32018-11-27 16:32:45 -05005242 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005243 return false;
5244 }
5245
5246 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5247 if (!buffer)
5248 {
5249 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madille0472f32018-11-27 16:32:45 -05005250 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005251 return false;
5252 }
5253
5254 const Extensions &extensions = context->getExtensions();
5255
5256 switch (pname)
5257 {
5258 case GL_BUFFER_USAGE:
5259 case GL_BUFFER_SIZE:
5260 break;
5261
5262 case GL_BUFFER_ACCESS_OES:
5263 if (!extensions.mapBuffer)
5264 {
Jamie Madill610640f2018-11-21 17:28:41 -05005265 context->validationError(GL_INVALID_ENUM,
5266 "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005267 return false;
5268 }
5269 break;
5270
5271 case GL_BUFFER_MAPPED:
5272 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5273 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5274 !extensions.mapBufferRange)
5275 {
Jamie Madill610640f2018-11-21 17:28:41 -05005276 context->validationError(GL_INVALID_ENUM,
5277 "pname requires OpenGL ES 3.0, "
5278 "GL_OES_mapbuffer or "
5279 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005280 return false;
5281 }
5282 break;
5283
5284 case GL_BUFFER_MAP_POINTER:
5285 if (!pointerVersion)
5286 {
Jamie Madill610640f2018-11-21 17:28:41 -05005287 context->validationError(
5288 GL_INVALID_ENUM,
5289 "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005290 return false;
5291 }
5292 break;
5293
5294 case GL_BUFFER_ACCESS_FLAGS:
5295 case GL_BUFFER_MAP_OFFSET:
5296 case GL_BUFFER_MAP_LENGTH:
5297 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5298 {
Jamie Madill610640f2018-11-21 17:28:41 -05005299 context->validationError(
5300 GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005301 return false;
5302 }
5303 break;
5304
Geoff Lang79b91402018-10-04 15:11:30 -04005305 case GL_MEMORY_SIZE_ANGLE:
5306 if (!context->getExtensions().memorySize)
5307 {
Jamie Madille0472f32018-11-27 16:32:45 -05005308 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005309 return false;
5310 }
5311 break;
5312
Jamie Madillbe849e42017-05-02 15:49:00 -04005313 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005314 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005315 return false;
5316 }
5317
5318 // All buffer parameter queries return one value.
5319 if (numParams)
5320 {
5321 *numParams = 1;
5322 }
5323
5324 return true;
5325}
5326
5327bool ValidateGetRenderbufferParameterivBase(Context *context,
5328 GLenum target,
5329 GLenum pname,
5330 GLsizei *length)
5331{
5332 if (length)
5333 {
5334 *length = 0;
5335 }
5336
5337 if (target != GL_RENDERBUFFER)
5338 {
Jamie Madille0472f32018-11-27 16:32:45 -05005339 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005340 return false;
5341 }
5342
5343 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5344 if (renderbuffer == nullptr)
5345 {
Jamie Madille0472f32018-11-27 16:32:45 -05005346 context->validationError(GL_INVALID_OPERATION, kRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005347 return false;
5348 }
5349
5350 switch (pname)
5351 {
5352 case GL_RENDERBUFFER_WIDTH:
5353 case GL_RENDERBUFFER_HEIGHT:
5354 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5355 case GL_RENDERBUFFER_RED_SIZE:
5356 case GL_RENDERBUFFER_GREEN_SIZE:
5357 case GL_RENDERBUFFER_BLUE_SIZE:
5358 case GL_RENDERBUFFER_ALPHA_SIZE:
5359 case GL_RENDERBUFFER_DEPTH_SIZE:
5360 case GL_RENDERBUFFER_STENCIL_SIZE:
5361 break;
5362
5363 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5364 if (!context->getExtensions().framebufferMultisample)
5365 {
Jamie Madille0472f32018-11-27 16:32:45 -05005366 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005367 return false;
5368 }
5369 break;
5370
Geoff Lang79b91402018-10-04 15:11:30 -04005371 case GL_MEMORY_SIZE_ANGLE:
5372 if (!context->getExtensions().memorySize)
5373 {
Jamie Madille0472f32018-11-27 16:32:45 -05005374 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005375 return false;
5376 }
5377 break;
5378
Jamie Madillbe849e42017-05-02 15:49:00 -04005379 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005380 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005381 return false;
5382 }
5383
5384 if (length)
5385 {
5386 *length = 1;
5387 }
5388 return true;
5389}
5390
5391bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5392{
5393 if (length)
5394 {
5395 *length = 0;
5396 }
5397
5398 if (GetValidShader(context, shader) == nullptr)
5399 {
5400 return false;
5401 }
5402
5403 switch (pname)
5404 {
5405 case GL_SHADER_TYPE:
5406 case GL_DELETE_STATUS:
5407 case GL_COMPILE_STATUS:
5408 case GL_INFO_LOG_LENGTH:
5409 case GL_SHADER_SOURCE_LENGTH:
5410 break;
5411
5412 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5413 if (!context->getExtensions().translatedShaderSource)
5414 {
Jamie Madille0472f32018-11-27 16:32:45 -05005415 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005416 return false;
5417 }
5418 break;
5419
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005420 case GL_COMPLETION_STATUS_KHR:
5421 if (!context->getExtensions().parallelShaderCompile)
5422 {
Jamie Madille0472f32018-11-27 16:32:45 -05005423 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005424 return false;
5425 }
5426 break;
5427
Jamie Madillbe849e42017-05-02 15:49:00 -04005428 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005429 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005430 return false;
5431 }
5432
5433 if (length)
5434 {
5435 *length = 1;
5436 }
5437 return true;
5438}
5439
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005440bool ValidateGetTexParameterBase(Context *context,
5441 TextureType target,
5442 GLenum pname,
5443 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005444{
5445 if (length)
5446 {
5447 *length = 0;
5448 }
5449
5450 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5451 {
Jamie Madille0472f32018-11-27 16:32:45 -05005452 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005453 return false;
5454 }
5455
5456 if (context->getTargetTexture(target) == nullptr)
5457 {
5458 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005459 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005460 return false;
5461 }
5462
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005463 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5464 {
Jamie Madille0472f32018-11-27 16:32:45 -05005465 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005466 return false;
5467 }
5468
Jamie Madillbe849e42017-05-02 15:49:00 -04005469 switch (pname)
5470 {
5471 case GL_TEXTURE_MAG_FILTER:
5472 case GL_TEXTURE_MIN_FILTER:
5473 case GL_TEXTURE_WRAP_S:
5474 case GL_TEXTURE_WRAP_T:
5475 break;
5476
5477 case GL_TEXTURE_USAGE_ANGLE:
5478 if (!context->getExtensions().textureUsage)
5479 {
Jamie Madille0472f32018-11-27 16:32:45 -05005480 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005481 return false;
5482 }
5483 break;
5484
5485 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005486 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005487 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005488 return false;
5489 }
5490 break;
5491
5492 case GL_TEXTURE_IMMUTABLE_FORMAT:
5493 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5494 {
Jamie Madille0472f32018-11-27 16:32:45 -05005495 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005496 return false;
5497 }
5498 break;
5499
5500 case GL_TEXTURE_WRAP_R:
5501 case GL_TEXTURE_IMMUTABLE_LEVELS:
5502 case GL_TEXTURE_SWIZZLE_R:
5503 case GL_TEXTURE_SWIZZLE_G:
5504 case GL_TEXTURE_SWIZZLE_B:
5505 case GL_TEXTURE_SWIZZLE_A:
5506 case GL_TEXTURE_BASE_LEVEL:
5507 case GL_TEXTURE_MAX_LEVEL:
5508 case GL_TEXTURE_MIN_LOD:
5509 case GL_TEXTURE_MAX_LOD:
5510 case GL_TEXTURE_COMPARE_MODE:
5511 case GL_TEXTURE_COMPARE_FUNC:
5512 if (context->getClientMajorVersion() < 3)
5513 {
Jamie Madill610640f2018-11-21 17:28:41 -05005514 context->validationError(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005515 return false;
5516 }
5517 break;
5518
5519 case GL_TEXTURE_SRGB_DECODE_EXT:
5520 if (!context->getExtensions().textureSRGBDecode)
5521 {
Jamie Madill610640f2018-11-21 17:28:41 -05005522 context->validationError(GL_INVALID_ENUM,
5523 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005524 return false;
5525 }
5526 break;
5527
Yunchao Hebacaa712018-01-30 14:01:39 +08005528 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5529 if (context->getClientVersion() < Version(3, 1))
5530 {
Jamie Madille0472f32018-11-27 16:32:45 -05005531 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005532 return false;
5533 }
5534 break;
5535
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005536 case GL_GENERATE_MIPMAP:
5537 case GL_TEXTURE_CROP_RECT_OES:
5538 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5539 // after GL_OES_draw_texture functionality implemented
5540 if (context->getClientMajorVersion() > 1)
5541 {
Jamie Madille0472f32018-11-27 16:32:45 -05005542 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005543 return false;
5544 }
5545 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005546
5547 case GL_MEMORY_SIZE_ANGLE:
5548 if (!context->getExtensions().memorySize)
5549 {
Jamie Madille0472f32018-11-27 16:32:45 -05005550 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005551 return false;
5552 }
5553 break;
5554
Till Rathmannb8543632018-10-02 19:46:14 +02005555 case GL_TEXTURE_BORDER_COLOR:
5556 if (!context->getExtensions().textureBorderClamp)
5557 {
Jamie Madille0472f32018-11-27 16:32:45 -05005558 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005559 return false;
5560 }
5561 break;
5562
Jamie Madillbe849e42017-05-02 15:49:00 -04005563 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005564 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005565 return false;
5566 }
5567
5568 if (length)
5569 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005570 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005571 }
5572 return true;
5573}
5574
5575bool ValidateGetVertexAttribBase(Context *context,
5576 GLuint index,
5577 GLenum pname,
5578 GLsizei *length,
5579 bool pointer,
5580 bool pureIntegerEntryPoint)
5581{
5582 if (length)
5583 {
5584 *length = 0;
5585 }
5586
5587 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5588 {
Jamie Madill610640f2018-11-21 17:28:41 -05005589 context->validationError(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005590 return false;
5591 }
5592
5593 if (index >= context->getCaps().maxVertexAttributes)
5594 {
Jamie Madille0472f32018-11-27 16:32:45 -05005595 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005596 return false;
5597 }
5598
5599 if (pointer)
5600 {
5601 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5602 {
Jamie Madille0472f32018-11-27 16:32:45 -05005603 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005604 return false;
5605 }
5606 }
5607 else
5608 {
5609 switch (pname)
5610 {
5611 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5612 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5613 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5614 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5615 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5616 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5617 case GL_CURRENT_VERTEX_ATTRIB:
5618 break;
5619
5620 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5621 static_assert(
5622 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5623 "ANGLE extension enums not equal to GL enums.");
5624 if (context->getClientMajorVersion() < 3 &&
5625 !context->getExtensions().instancedArrays)
5626 {
Jamie Madill610640f2018-11-21 17:28:41 -05005627 context->validationError(GL_INVALID_ENUM,
5628 "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5629 "requires OpenGL ES 3.0 or "
5630 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005631 return false;
5632 }
5633 break;
5634
5635 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5636 if (context->getClientMajorVersion() < 3)
5637 {
Jamie Madill610640f2018-11-21 17:28:41 -05005638 context->validationError(
5639 GL_INVALID_ENUM, "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005640 return false;
5641 }
5642 break;
5643
5644 case GL_VERTEX_ATTRIB_BINDING:
5645 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5646 if (context->getClientVersion() < ES_3_1)
5647 {
Jamie Madill610640f2018-11-21 17:28:41 -05005648 context->validationError(GL_INVALID_ENUM,
5649 "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005650 return false;
5651 }
5652 break;
5653
5654 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005655 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005656 return false;
5657 }
5658 }
5659
5660 if (length)
5661 {
5662 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5663 {
5664 *length = 4;
5665 }
5666 else
5667 {
5668 *length = 1;
5669 }
5670 }
5671
5672 return true;
5673}
5674
Jamie Madill4928b7c2017-06-20 12:57:39 -04005675bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005676 GLint x,
5677 GLint y,
5678 GLsizei width,
5679 GLsizei height,
5680 GLenum format,
5681 GLenum type,
5682 GLsizei bufSize,
5683 GLsizei *length,
5684 GLsizei *columns,
5685 GLsizei *rows,
5686 void *pixels)
5687{
5688 if (length != nullptr)
5689 {
5690 *length = 0;
5691 }
5692 if (rows != nullptr)
5693 {
5694 *rows = 0;
5695 }
5696 if (columns != nullptr)
5697 {
5698 *columns = 0;
5699 }
5700
5701 if (width < 0 || height < 0)
5702 {
Jamie Madille0472f32018-11-27 16:32:45 -05005703 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005704 return false;
5705 }
5706
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005707 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005708
Jamie Madill427064d2018-04-13 16:20:34 -04005709 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005710 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005711 return false;
5712 }
5713
Jamie Madille98b1b52018-03-08 09:47:23 -05005714 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005715 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005716 return false;
5717 }
5718
Jamie Madill690c8eb2018-03-12 15:20:03 -04005719 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005720 ASSERT(framebuffer);
5721
5722 if (framebuffer->getReadBufferState() == GL_NONE)
5723 {
Jamie Madille0472f32018-11-27 16:32:45 -05005724 context->validationError(GL_INVALID_OPERATION, kReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005725 return false;
5726 }
5727
5728 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5729 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5730 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5731 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5732 // situation is an application error that would lead to a crash in ANGLE.
5733 if (readBuffer == nullptr)
5734 {
Jamie Madille0472f32018-11-27 16:32:45 -05005735 context->validationError(GL_INVALID_OPERATION, kMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005736 return false;
5737 }
5738
Martin Radev28031682017-07-28 14:47:56 +03005739 // ANGLE_multiview, Revision 1:
5740 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005741 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5742 // in the current read framebuffer is more than one.
5743 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005744 {
Jamie Madill610640f2018-11-21 17:28:41 -05005745 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
5746 "Attempting to read from a multi-view framebuffer.");
Martin Radev28031682017-07-28 14:47:56 +03005747 return false;
5748 }
5749
Geoff Lang280ba992017-04-18 16:30:58 -04005750 if (context->getExtensions().webglCompatibility)
5751 {
5752 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5753 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5754 // and type before validating the combination of format and type. However, the
5755 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5756 // verifies that GL_INVALID_OPERATION is generated.
5757 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5758 // dEQP/WebGL.
5759 if (!ValidReadPixelsFormatEnum(context, format))
5760 {
Jamie Madille0472f32018-11-27 16:32:45 -05005761 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005762 return false;
5763 }
5764
5765 if (!ValidReadPixelsTypeEnum(context, type))
5766 {
Jamie Madille0472f32018-11-27 16:32:45 -05005767 context->validationError(GL_INVALID_ENUM, kInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005768 return false;
5769 }
5770 }
5771
Jamie Madill690c8eb2018-03-12 15:20:03 -04005772 GLenum currentFormat = GL_NONE;
5773 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5774
5775 GLenum currentType = GL_NONE;
5776 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5777
Jamie Madillbe849e42017-05-02 15:49:00 -04005778 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5779
5780 bool validFormatTypeCombination =
5781 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5782
5783 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5784 {
Jamie Madille0472f32018-11-27 16:32:45 -05005785 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005786 return false;
5787 }
5788
5789 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005790 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005791 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5792 {
5793 // ...the buffer object's data store is currently mapped.
Jamie Madill610640f2018-11-21 17:28:41 -05005794 context->validationError(GL_INVALID_OPERATION, "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005795 return false;
5796 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005797 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5798 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5799 {
Jamie Madille0472f32018-11-27 16:32:45 -05005800 context->validationError(GL_INVALID_OPERATION, kPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005801 return false;
5802 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005803
5804 // .. the data would be packed to the buffer object such that the memory writes required
5805 // would exceed the data store size.
5806 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005807 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005808 const auto &pack = context->getGLState().getPackState();
5809
Jamie Madillca2ff382018-07-11 09:01:17 -04005810 GLuint endByte = 0;
5811 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005812 {
Jamie Madille0472f32018-11-27 16:32:45 -05005813 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005814 return false;
5815 }
5816
Jamie Madillbe849e42017-05-02 15:49:00 -04005817 if (bufSize >= 0)
5818 {
5819 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5820 {
Jamie Madille0472f32018-11-27 16:32:45 -05005821 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005822 return false;
5823 }
5824 }
5825
5826 if (pixelPackBuffer != nullptr)
5827 {
5828 CheckedNumeric<size_t> checkedEndByte(endByte);
5829 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5830 checkedEndByte += checkedOffset;
5831
5832 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5833 {
5834 // Overflow past the end of the buffer
Jamie Madille0472f32018-11-27 16:32:45 -05005835 context->validationError(GL_INVALID_OPERATION, kParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005836 return false;
5837 }
5838 }
5839
5840 if (pixelPackBuffer == nullptr && length != nullptr)
5841 {
5842 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5843 {
Jamie Madille0472f32018-11-27 16:32:45 -05005844 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005845 return false;
5846 }
5847
5848 *length = static_cast<GLsizei>(endByte);
5849 }
5850
Geoff Langa953b522018-02-21 16:56:23 -05005851 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005852 angle::CheckedNumeric<int> clippedExtent(length);
5853 if (start < 0)
5854 {
5855 // "subtract" the area that is less than 0
5856 clippedExtent += start;
5857 }
5858
Geoff Langa953b522018-02-21 16:56:23 -05005859 angle::CheckedNumeric<int> readExtent = start;
5860 readExtent += length;
5861 if (!readExtent.IsValid())
5862 {
5863 return false;
5864 }
5865
5866 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005867 {
5868 // Subtract the region to the right of the read buffer
5869 clippedExtent -= (readExtent - bufferSize);
5870 }
5871
5872 if (!clippedExtent.IsValid())
5873 {
Geoff Langa953b522018-02-21 16:56:23 -05005874 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005875 }
5876
Geoff Langa953b522018-02-21 16:56:23 -05005877 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5878 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005879 };
5880
Geoff Langa953b522018-02-21 16:56:23 -05005881 GLsizei writtenColumns = 0;
5882 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5883 {
Jamie Madille0472f32018-11-27 16:32:45 -05005884 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005885 return false;
5886 }
5887
5888 GLsizei writtenRows = 0;
5889 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5890 {
Jamie Madille0472f32018-11-27 16:32:45 -05005891 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005892 return false;
5893 }
5894
Jamie Madillbe849e42017-05-02 15:49:00 -04005895 if (columns != nullptr)
5896 {
Geoff Langa953b522018-02-21 16:56:23 -05005897 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005898 }
5899
5900 if (rows != nullptr)
5901 {
Geoff Langa953b522018-02-21 16:56:23 -05005902 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005903 }
5904
5905 return true;
5906}
5907
5908template <typename ParamType>
5909bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005910 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005911 GLenum pname,
5912 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005913 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005914 const ParamType *params)
5915{
5916 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5917 {
Jamie Madille0472f32018-11-27 16:32:45 -05005918 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005919 return false;
5920 }
5921
5922 if (context->getTargetTexture(target) == nullptr)
5923 {
5924 // Should only be possible for external textures
Jamie Madille0472f32018-11-27 16:32:45 -05005925 context->validationError(GL_INVALID_ENUM, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005926 return false;
5927 }
5928
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005929 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005930 if (bufSize >= 0 && bufSize < minBufSize)
5931 {
Jamie Madille0472f32018-11-27 16:32:45 -05005932 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 return false;
5934 }
5935
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005936 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5937 {
Jamie Madille0472f32018-11-27 16:32:45 -05005938 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005939 return false;
5940 }
5941
Jamie Madillbe849e42017-05-02 15:49:00 -04005942 switch (pname)
5943 {
5944 case GL_TEXTURE_WRAP_R:
5945 case GL_TEXTURE_SWIZZLE_R:
5946 case GL_TEXTURE_SWIZZLE_G:
5947 case GL_TEXTURE_SWIZZLE_B:
5948 case GL_TEXTURE_SWIZZLE_A:
5949 case GL_TEXTURE_BASE_LEVEL:
5950 case GL_TEXTURE_MAX_LEVEL:
5951 case GL_TEXTURE_COMPARE_MODE:
5952 case GL_TEXTURE_COMPARE_FUNC:
5953 case GL_TEXTURE_MIN_LOD:
5954 case GL_TEXTURE_MAX_LOD:
5955 if (context->getClientMajorVersion() < 3)
5956 {
Jamie Madille0472f32018-11-27 16:32:45 -05005957 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005958 return false;
5959 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005960 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005961 {
Jamie Madill610640f2018-11-21 17:28:41 -05005962 context->validationError(GL_INVALID_ENUM,
5963 "ES3 texture parameters are not "
5964 "available without "
5965 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 return false;
5967 }
5968 break;
5969
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005970 case GL_GENERATE_MIPMAP:
5971 case GL_TEXTURE_CROP_RECT_OES:
5972 if (context->getClientMajorVersion() > 1)
5973 {
Jamie Madille0472f32018-11-27 16:32:45 -05005974 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005975 return false;
5976 }
5977 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005978 default:
5979 break;
5980 }
5981
Olli Etuahod310a432018-08-24 15:40:23 +03005982 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005983 {
5984 switch (pname)
5985 {
5986 case GL_TEXTURE_MIN_FILTER:
5987 case GL_TEXTURE_MAG_FILTER:
5988 case GL_TEXTURE_WRAP_S:
5989 case GL_TEXTURE_WRAP_T:
5990 case GL_TEXTURE_WRAP_R:
5991 case GL_TEXTURE_MIN_LOD:
5992 case GL_TEXTURE_MAX_LOD:
5993 case GL_TEXTURE_COMPARE_MODE:
5994 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005995 case GL_TEXTURE_BORDER_COLOR:
Jamie Madill610640f2018-11-21 17:28:41 -05005996 context->validationError(GL_INVALID_ENUM,
5997 "Invalid parameter for 2D multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08005998 return false;
5999 }
6000 }
6001
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 switch (pname)
6003 {
6004 case GL_TEXTURE_WRAP_S:
6005 case GL_TEXTURE_WRAP_T:
6006 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006007 {
6008 bool restrictedWrapModes =
6009 target == TextureType::External || target == TextureType::Rectangle;
6010 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04006011 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006012 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006014 }
6015 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006016
6017 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006018 {
6019 bool restrictedMinFilter =
6020 target == TextureType::External || target == TextureType::Rectangle;
6021 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006023 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006025 }
6026 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006027
6028 case GL_TEXTURE_MAG_FILTER:
6029 if (!ValidateTextureMagFilterValue(context, params))
6030 {
6031 return false;
6032 }
6033 break;
6034
6035 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04006036 if (!context->getExtensions().textureUsage)
6037 {
Jamie Madille0472f32018-11-27 16:32:45 -05006038 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04006039 return false;
6040 }
6041
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 switch (ConvertToGLenum(params[0]))
6043 {
6044 case GL_NONE:
6045 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
6046 break;
6047
6048 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006049 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
6052 break;
6053
6054 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006055 {
6056 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6057 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006059 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006060 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006061 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
6062 }
6063 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006064
6065 case GL_TEXTURE_MIN_LOD:
6066 case GL_TEXTURE_MAX_LOD:
6067 // any value is permissible
6068 break;
6069
6070 case GL_TEXTURE_COMPARE_MODE:
6071 if (!ValidateTextureCompareModeValue(context, params))
6072 {
6073 return false;
6074 }
6075 break;
6076
6077 case GL_TEXTURE_COMPARE_FUNC:
6078 if (!ValidateTextureCompareFuncValue(context, params))
6079 {
6080 return false;
6081 }
6082 break;
6083
6084 case GL_TEXTURE_SWIZZLE_R:
6085 case GL_TEXTURE_SWIZZLE_G:
6086 case GL_TEXTURE_SWIZZLE_B:
6087 case GL_TEXTURE_SWIZZLE_A:
6088 switch (ConvertToGLenum(params[0]))
6089 {
6090 case GL_RED:
6091 case GL_GREEN:
6092 case GL_BLUE:
6093 case GL_ALPHA:
6094 case GL_ZERO:
6095 case GL_ONE:
6096 break;
6097
6098 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006099 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006100 return false;
6101 }
6102 break;
6103
6104 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006105 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006106 {
Jamie Madill610640f2018-11-21 17:28:41 -05006107 context->validationError(GL_INVALID_VALUE, "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006108 return false;
6109 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006110 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006111 {
Jamie Madill610640f2018-11-21 17:28:41 -05006112 context->validationError(GL_INVALID_OPERATION,
6113 "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 return false;
6115 }
Olli Etuahod310a432018-08-24 15:40:23 +03006116 if ((target == TextureType::_2DMultisample ||
6117 target == TextureType::_2DMultisampleArray) &&
6118 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006119 {
Jamie Madill610640f2018-11-21 17:28:41 -05006120 context->validationError(GL_INVALID_OPERATION,
6121 "Base level must be 0 for multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08006122 return false;
6123 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006124 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006125 {
Jamie Madill610640f2018-11-21 17:28:41 -05006126 context->validationError(GL_INVALID_OPERATION,
6127 "Base level must be 0 for rectangle textures.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006128 return false;
6129 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006130 break;
6131
6132 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006133 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006134 {
Jamie Madille0472f32018-11-27 16:32:45 -05006135 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 return false;
6137 }
6138 break;
6139
6140 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6141 if (context->getClientVersion() < Version(3, 1))
6142 {
Jamie Madille0472f32018-11-27 16:32:45 -05006143 context->validationError(GL_INVALID_ENUM, kEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 return false;
6145 }
6146 switch (ConvertToGLenum(params[0]))
6147 {
6148 case GL_DEPTH_COMPONENT:
6149 case GL_STENCIL_INDEX:
6150 break;
6151
6152 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006153 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006154 return false;
6155 }
6156 break;
6157
6158 case GL_TEXTURE_SRGB_DECODE_EXT:
6159 if (!ValidateTextureSRGBDecodeValue(context, params))
6160 {
6161 return false;
6162 }
6163 break;
6164
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006165 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006166 if (context->getClientMajorVersion() > 1)
6167 {
Jamie Madille0472f32018-11-27 16:32:45 -05006168 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006169 return false;
6170 }
6171 break;
Till Rathmannb8543632018-10-02 19:46:14 +02006172
6173 case GL_TEXTURE_CROP_RECT_OES:
6174 if (context->getClientMajorVersion() > 1)
6175 {
Jamie Madille0472f32018-11-27 16:32:45 -05006176 context->validationError(GL_INVALID_ENUM, kGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02006177 return false;
6178 }
6179 if (!vectorParams)
6180 {
Jamie Madille0472f32018-11-27 16:32:45 -05006181 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006182 return false;
6183 }
6184 break;
6185
6186 case GL_TEXTURE_BORDER_COLOR:
6187 if (!context->getExtensions().textureBorderClamp)
6188 {
Jamie Madille0472f32018-11-27 16:32:45 -05006189 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006190 return false;
6191 }
6192 if (!vectorParams)
6193 {
Jamie Madille0472f32018-11-27 16:32:45 -05006194 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006195 return false;
6196 }
6197 break;
6198
Jamie Madillbe849e42017-05-02 15:49:00 -04006199 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006200 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006201 return false;
6202 }
6203
6204 return true;
6205}
6206
Till Rathmannb8543632018-10-02 19:46:14 +02006207template bool ValidateTexParameterBase(Context *,
6208 TextureType,
6209 GLenum,
6210 GLsizei,
6211 bool,
6212 const GLfloat *);
6213template bool ValidateTexParameterBase(Context *,
6214 TextureType,
6215 GLenum,
6216 GLsizei,
6217 bool,
6218 const GLint *);
6219template bool ValidateTexParameterBase(Context *,
6220 TextureType,
6221 GLenum,
6222 GLsizei,
6223 bool,
6224 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006225
Jamie Madill5b772312018-03-08 20:28:32 -05006226bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006227{
6228 if (index >= MAX_VERTEX_ATTRIBS)
6229 {
Jamie Madille0472f32018-11-27 16:32:45 -05006230 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04006231 return false;
6232 }
6233
6234 return true;
6235}
6236
6237bool ValidateGetActiveUniformBlockivBase(Context *context,
6238 GLuint program,
6239 GLuint uniformBlockIndex,
6240 GLenum pname,
6241 GLsizei *length)
6242{
6243 if (length)
6244 {
6245 *length = 0;
6246 }
6247
6248 if (context->getClientMajorVersion() < 3)
6249 {
Jamie Madille0472f32018-11-27 16:32:45 -05006250 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04006251 return false;
6252 }
6253
6254 Program *programObject = GetValidProgram(context, program);
6255 if (!programObject)
6256 {
6257 return false;
6258 }
6259
6260 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6261 {
Jamie Madill610640f2018-11-21 17:28:41 -05006262 context->validationError(GL_INVALID_VALUE,
6263 "uniformBlockIndex exceeds active uniform block count.");
Jamie Madill12e957f2017-08-26 21:42:26 -04006264 return false;
6265 }
6266
6267 switch (pname)
6268 {
6269 case GL_UNIFORM_BLOCK_BINDING:
6270 case GL_UNIFORM_BLOCK_DATA_SIZE:
6271 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6272 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6273 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6274 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6275 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6276 break;
6277
6278 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006279 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04006280 return false;
6281 }
6282
6283 if (length)
6284 {
6285 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6286 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006287 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006288 programObject->getUniformBlockByIndex(uniformBlockIndex);
6289 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6290 }
6291 else
6292 {
6293 *length = 1;
6294 }
6295 }
6296
6297 return true;
6298}
6299
Jamie Madill9696d072017-08-26 23:19:57 -04006300template <typename ParamType>
6301bool ValidateSamplerParameterBase(Context *context,
6302 GLuint sampler,
6303 GLenum pname,
6304 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02006305 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04006306 ParamType *params)
6307{
6308 if (context->getClientMajorVersion() < 3)
6309 {
Jamie Madille0472f32018-11-27 16:32:45 -05006310 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006311 return false;
6312 }
6313
6314 if (!context->isSampler(sampler))
6315 {
Jamie Madille0472f32018-11-27 16:32:45 -05006316 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006317 return false;
6318 }
6319
Till Rathmannb8543632018-10-02 19:46:14 +02006320 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006321 if (bufSize >= 0 && bufSize < minBufSize)
6322 {
Jamie Madille0472f32018-11-27 16:32:45 -05006323 context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006324 return false;
6325 }
6326
6327 switch (pname)
6328 {
6329 case GL_TEXTURE_WRAP_S:
6330 case GL_TEXTURE_WRAP_T:
6331 case GL_TEXTURE_WRAP_R:
6332 if (!ValidateTextureWrapModeValue(context, params, false))
6333 {
6334 return false;
6335 }
6336 break;
6337
6338 case GL_TEXTURE_MIN_FILTER:
6339 if (!ValidateTextureMinFilterValue(context, params, false))
6340 {
6341 return false;
6342 }
6343 break;
6344
6345 case GL_TEXTURE_MAG_FILTER:
6346 if (!ValidateTextureMagFilterValue(context, params))
6347 {
6348 return false;
6349 }
6350 break;
6351
6352 case GL_TEXTURE_MIN_LOD:
6353 case GL_TEXTURE_MAX_LOD:
6354 // any value is permissible
6355 break;
6356
6357 case GL_TEXTURE_COMPARE_MODE:
6358 if (!ValidateTextureCompareModeValue(context, params))
6359 {
6360 return false;
6361 }
6362 break;
6363
6364 case GL_TEXTURE_COMPARE_FUNC:
6365 if (!ValidateTextureCompareFuncValue(context, params))
6366 {
6367 return false;
6368 }
6369 break;
6370
6371 case GL_TEXTURE_SRGB_DECODE_EXT:
6372 if (!ValidateTextureSRGBDecodeValue(context, params))
6373 {
6374 return false;
6375 }
6376 break;
6377
Luc Ferron1b1a8642018-01-23 15:12:01 -05006378 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6379 {
6380 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6381 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6382 {
6383 return false;
6384 }
6385 }
6386 break;
6387
Till Rathmannb8543632018-10-02 19:46:14 +02006388 case GL_TEXTURE_BORDER_COLOR:
6389 if (!context->getExtensions().textureBorderClamp)
6390 {
Jamie Madille0472f32018-11-27 16:32:45 -05006391 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006392 return false;
6393 }
6394 if (!vectorParams)
6395 {
Jamie Madille0472f32018-11-27 16:32:45 -05006396 context->validationError(GL_INVALID_ENUM, kInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006397 return false;
6398 }
6399 break;
6400
Jamie Madill9696d072017-08-26 23:19:57 -04006401 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006402 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006403 return false;
6404 }
6405
6406 return true;
6407}
6408
Till Rathmannb8543632018-10-02 19:46:14 +02006409template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6410template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6411template bool ValidateSamplerParameterBase(Context *,
6412 GLuint,
6413 GLenum,
6414 GLsizei,
6415 bool,
6416 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006417
6418bool ValidateGetSamplerParameterBase(Context *context,
6419 GLuint sampler,
6420 GLenum pname,
6421 GLsizei *length)
6422{
6423 if (length)
6424 {
6425 *length = 0;
6426 }
6427
6428 if (context->getClientMajorVersion() < 3)
6429 {
Jamie Madille0472f32018-11-27 16:32:45 -05006430 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006431 return false;
6432 }
6433
6434 if (!context->isSampler(sampler))
6435 {
Jamie Madille0472f32018-11-27 16:32:45 -05006436 context->validationError(GL_INVALID_OPERATION, kInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006437 return false;
6438 }
6439
6440 switch (pname)
6441 {
6442 case GL_TEXTURE_WRAP_S:
6443 case GL_TEXTURE_WRAP_T:
6444 case GL_TEXTURE_WRAP_R:
6445 case GL_TEXTURE_MIN_FILTER:
6446 case GL_TEXTURE_MAG_FILTER:
6447 case GL_TEXTURE_MIN_LOD:
6448 case GL_TEXTURE_MAX_LOD:
6449 case GL_TEXTURE_COMPARE_MODE:
6450 case GL_TEXTURE_COMPARE_FUNC:
6451 break;
6452
Luc Ferron1b1a8642018-01-23 15:12:01 -05006453 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6454 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6455 {
6456 return false;
6457 }
6458 break;
6459
Jamie Madill9696d072017-08-26 23:19:57 -04006460 case GL_TEXTURE_SRGB_DECODE_EXT:
6461 if (!context->getExtensions().textureSRGBDecode)
6462 {
Jamie Madill610640f2018-11-21 17:28:41 -05006463 context->validationError(GL_INVALID_ENUM,
6464 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madill9696d072017-08-26 23:19:57 -04006465 return false;
6466 }
6467 break;
6468
Till Rathmannb8543632018-10-02 19:46:14 +02006469 case GL_TEXTURE_BORDER_COLOR:
6470 if (!context->getExtensions().textureBorderClamp)
6471 {
Jamie Madille0472f32018-11-27 16:32:45 -05006472 context->validationError(GL_INVALID_ENUM, kExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006473 return false;
6474 }
6475 break;
6476
Jamie Madill9696d072017-08-26 23:19:57 -04006477 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006478 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006479 return false;
6480 }
6481
6482 if (length)
6483 {
Till Rathmannb8543632018-10-02 19:46:14 +02006484 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006485 }
6486 return true;
6487}
6488
6489bool ValidateGetInternalFormativBase(Context *context,
6490 GLenum target,
6491 GLenum internalformat,
6492 GLenum pname,
6493 GLsizei bufSize,
6494 GLsizei *numParams)
6495{
6496 if (numParams)
6497 {
6498 *numParams = 0;
6499 }
6500
6501 if (context->getClientMajorVersion() < 3)
6502 {
Jamie Madille0472f32018-11-27 16:32:45 -05006503 context->validationError(GL_INVALID_OPERATION, kES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006504 return false;
6505 }
6506
6507 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006508 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006509 {
Jamie Madill610640f2018-11-21 17:28:41 -05006510 context->validationError(GL_INVALID_ENUM, "Internal format is not renderable.");
Jamie Madill9696d072017-08-26 23:19:57 -04006511 return false;
6512 }
6513
6514 switch (target)
6515 {
6516 case GL_RENDERBUFFER:
6517 break;
6518
6519 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006520 if (context->getClientVersion() < ES_3_1 &&
6521 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006522 {
Jamie Madill610640f2018-11-21 17:28:41 -05006523 context->validationError(GL_INVALID_ENUM,
Jamie Madille0472f32018-11-27 16:32:45 -05006524 kMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006525 return false;
6526 }
6527 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006528 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6529 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006530 {
Jamie Madille0472f32018-11-27 16:32:45 -05006531 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006532 return false;
6533 }
6534 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006535 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006536 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006537 return false;
6538 }
6539
6540 if (bufSize < 0)
6541 {
Jamie Madille0472f32018-11-27 16:32:45 -05006542 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006543 return false;
6544 }
6545
6546 GLsizei maxWriteParams = 0;
6547 switch (pname)
6548 {
6549 case GL_NUM_SAMPLE_COUNTS:
6550 maxWriteParams = 1;
6551 break;
6552
6553 case GL_SAMPLES:
6554 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6555 break;
6556
6557 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006558 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006559 return false;
6560 }
6561
6562 if (numParams)
6563 {
6564 // glGetInternalFormativ will not overflow bufSize
6565 *numParams = std::min(bufSize, maxWriteParams);
6566 }
6567
6568 return true;
6569}
6570
Jamie Madille98b1b52018-03-08 09:47:23 -05006571bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6572{
Jamie Madill427064d2018-04-13 16:20:34 -04006573 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006574 {
Jamie Madille0472f32018-11-27 16:32:45 -05006575 context->validationError(GL_INVALID_OPERATION, kInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006576 return false;
6577 }
6578 return true;
6579}
6580
Lingfeng Yang038dd532018-03-29 17:31:52 -07006581bool ValidateMultitextureUnit(Context *context, GLenum texture)
6582{
6583 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6584 {
Jamie Madille0472f32018-11-27 16:32:45 -05006585 context->validationError(GL_INVALID_ENUM, kInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006586 return false;
6587 }
6588 return true;
6589}
6590
Olli Etuahod310a432018-08-24 15:40:23 +03006591bool ValidateTexStorageMultisample(Context *context,
6592 TextureType target,
6593 GLsizei samples,
6594 GLint internalFormat,
6595 GLsizei width,
6596 GLsizei height)
6597{
6598 const Caps &caps = context->getCaps();
6599 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6600 static_cast<GLuint>(height) > caps.max2DTextureSize)
6601 {
Jamie Madille0472f32018-11-27 16:32:45 -05006602 context->validationError(GL_INVALID_VALUE, kTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006603 return false;
6604 }
6605
6606 if (samples == 0)
6607 {
Jamie Madille0472f32018-11-27 16:32:45 -05006608 context->validationError(GL_INVALID_VALUE, kSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006609 return false;
6610 }
6611
6612 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6613 if (!formatCaps.textureAttachment)
6614 {
Jamie Madille0472f32018-11-27 16:32:45 -05006615 context->validationError(GL_INVALID_ENUM, kRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006616 return false;
6617 }
6618
6619 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6620 // is one of the unsized base internalformats listed in table 8.11.
6621 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6622 if (formatInfo.internalFormat == GL_NONE)
6623 {
Jamie Madille0472f32018-11-27 16:32:45 -05006624 context->validationError(GL_INVALID_ENUM, kUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006625 return false;
6626 }
6627
6628 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6629 {
Jamie Madille0472f32018-11-27 16:32:45 -05006630 context->validationError(GL_INVALID_OPERATION, kSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006631 return false;
6632 }
6633
6634 Texture *texture = context->getTargetTexture(target);
6635 if (!texture || texture->id() == 0)
6636 {
Jamie Madille0472f32018-11-27 16:32:45 -05006637 context->validationError(GL_INVALID_OPERATION, kZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006638 return false;
6639 }
6640
6641 if (texture->getImmutableFormat())
6642 {
Jamie Madille0472f32018-11-27 16:32:45 -05006643 context->validationError(GL_INVALID_OPERATION, kImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006644 return false;
6645 }
6646 return true;
6647}
6648
Yizhou Jiang7818a852018-09-06 15:02:04 +08006649bool ValidateTexStorage2DMultisampleBase(Context *context,
6650 TextureType target,
6651 GLsizei samples,
6652 GLint internalFormat,
6653 GLsizei width,
6654 GLsizei height)
6655{
6656 if (target != TextureType::_2DMultisample)
6657 {
Jamie Madille0472f32018-11-27 16:32:45 -05006658 context->validationError(GL_INVALID_ENUM, kInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006659 return false;
6660 }
6661
6662 if (width < 1 || height < 1)
6663 {
Jamie Madille0472f32018-11-27 16:32:45 -05006664 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006665 return false;
6666 }
6667
6668 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6669}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006670
6671bool ValidateGetTexLevelParameterBase(Context *context,
6672 TextureTarget target,
6673 GLint level,
6674 GLenum pname,
6675 GLsizei *length)
6676{
6677
6678 if (length)
6679 {
6680 *length = 0;
6681 }
6682
6683 TextureType type = TextureTargetToType(target);
6684
6685 if (!ValidTexLevelDestinationTarget(context, type))
6686 {
Jamie Madille0472f32018-11-27 16:32:45 -05006687 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006688 return false;
6689 }
6690
6691 if (context->getTargetTexture(type) == nullptr)
6692 {
Jamie Madill610640f2018-11-21 17:28:41 -05006693 context->validationError(GL_INVALID_ENUM, "No texture bound.");
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006694 return false;
6695 }
6696
6697 if (!ValidMipLevel(context, type, level))
6698 {
Jamie Madille0472f32018-11-27 16:32:45 -05006699 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006700 return false;
6701 }
6702
6703 switch (pname)
6704 {
6705 case GL_TEXTURE_RED_TYPE:
6706 case GL_TEXTURE_GREEN_TYPE:
6707 case GL_TEXTURE_BLUE_TYPE:
6708 case GL_TEXTURE_ALPHA_TYPE:
6709 case GL_TEXTURE_DEPTH_TYPE:
6710 break;
6711 case GL_TEXTURE_RED_SIZE:
6712 case GL_TEXTURE_GREEN_SIZE:
6713 case GL_TEXTURE_BLUE_SIZE:
6714 case GL_TEXTURE_ALPHA_SIZE:
6715 case GL_TEXTURE_DEPTH_SIZE:
6716 case GL_TEXTURE_STENCIL_SIZE:
6717 case GL_TEXTURE_SHARED_SIZE:
6718 break;
6719 case GL_TEXTURE_INTERNAL_FORMAT:
6720 case GL_TEXTURE_WIDTH:
6721 case GL_TEXTURE_HEIGHT:
6722 case GL_TEXTURE_DEPTH:
6723 break;
6724 case GL_TEXTURE_SAMPLES:
6725 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6726 break;
6727 case GL_TEXTURE_COMPRESSED:
6728 break;
6729 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006730 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006731 return false;
6732 }
6733
6734 if (length)
6735 {
6736 *length = 1;
6737 }
6738 return true;
6739}
Yizhou Jiang7310da32018-11-05 14:40:01 +08006740
6741bool ValidateGetMultisamplefvBase(Context *context, GLenum pname, GLuint index, GLfloat *val)
6742{
6743 if (pname != GL_SAMPLE_POSITION)
6744 {
6745 context->validationError(GL_INVALID_ENUM, kInvalidPname);
6746 return false;
6747 }
6748
6749 Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
6750 GLint samples = framebuffer->getSamples(context);
6751
6752 if (index >= static_cast<GLuint>(samples))
6753 {
6754 context->validationError(GL_INVALID_VALUE, kIndexExceedsSamples);
6755 return false;
6756 }
6757
6758 return true;
6759}
6760
6761bool ValidateSampleMaskiBase(Context *context, GLuint maskNumber, GLbitfield mask)
6762{
6763 if (maskNumber >= context->getCaps().maxSampleMaskWords)
6764 {
6765 context->validationError(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
6766 return false;
6767 }
6768
6769 return true;
6770}
Jamie Madillc29968b2016-01-20 11:17:23 -05006771} // namespace gl