blob: 84aba2b8aad6b5759447ddef61a21b39f27d10d2 [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 Madill1ca74672015-07-21 15:14:11 -040036namespace
37{
Luc Ferron9dbaeba2018-02-01 07:26:59 -050038bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
39{
40 // List of compressed format that require that the texture size is smaller than or a multiple of
41 // the compressed block size.
42 switch (internalFormat)
43 {
44 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
45 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
46 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
47 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
48 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
49 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
50 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
51 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
52 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
53 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
54 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
55 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
56 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
57 case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
58 case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +030059 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
60 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
61 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
62 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Luc Ferron9dbaeba2018-02-01 07:26:59 -050063 return true;
jchen10a99ed552017-09-22 08:10:32 +080064
Luc Ferron9dbaeba2018-02-01 07:26:59 -050065 default:
66 return false;
67 }
68}
69bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
70{
71 // Compressed sub textures have additional formats that requires exact size.
72 // ES 3.1, Section 8.7, Page 171
73 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
74 IsETC2EACFormat(internalFormat);
75}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030076
77bool DifferenceCanOverflow(GLint a, GLint b)
78{
79 CheckedNumeric<GLint> checkedA(a);
80 checkedA -= b;
81 // Use negation to make sure that the difference can't overflow regardless of the order.
82 checkedA = -checkedA;
83 return !checkedA.IsValid();
84}
85
Jamie Madill16e28fd2018-09-12 11:03:05 -040086bool ValidateDrawAttribsImpl(Context *context, GLint primcount, GLint maxVertex)
Jamie Madill1ca74672015-07-21 15:14:11 -040087{
Jamie Madill51af38b2018-04-15 08:50:56 -040088 // If we're drawing zero vertices, we have enough data.
Jamie Madill2da53562018-08-01 11:34:47 -040089 ASSERT(primcount > 0);
Jamie Madill51af38b2018-04-15 08:50:56 -040090
Jamie Madill88602e62018-08-08 12:49:30 -040091 // An overflow can happen when adding the offset. Check against a special constant.
92 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
93 VertexAttribute::kIntegerOverflow ||
94 context->getStateCache().getInstancedVertexElementLimit() ==
95 VertexAttribute::kIntegerOverflow)
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040096 {
Jamie Madill610640f2018-11-21 17:28:41 -050097 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040098 return false;
99 }
100
101 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
102 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
Jamie Madill610640f2018-11-21 17:28:41 -0500103 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientVertexBufferSize);
Jamie Madilla2d1d2d2018-08-01 11:34:46 -0400104 return false;
Jamie Madill1ca74672015-07-21 15:14:11 -0400105}
106
Jamie Madill16e28fd2018-09-12 11:03:05 -0400107ANGLE_INLINE bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex)
108{
109 if (maxVertex <= context->getStateCache().getNonInstancedVertexElementLimit() &&
110 (primcount - 1) <= context->getStateCache().getInstancedVertexElementLimit())
111 {
112 return true;
113 }
114 else
115 {
116 return ValidateDrawAttribsImpl(context, primcount, maxVertex);
117 }
118}
119
Jamie Madill5b772312018-03-08 20:28:32 -0500120bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -0400121{
122 switch (type)
123 {
124 // Types referenced in Table 3.4 of the ES 2.0.25 spec
125 case GL_UNSIGNED_BYTE:
126 case GL_UNSIGNED_SHORT_4_4_4_4:
127 case GL_UNSIGNED_SHORT_5_5_5_1:
128 case GL_UNSIGNED_SHORT_5_6_5:
129 return context->getClientVersion() >= ES_2_0;
130
131 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
132 case GL_BYTE:
133 case GL_INT:
134 case GL_SHORT:
135 case GL_UNSIGNED_INT:
136 case GL_UNSIGNED_INT_10F_11F_11F_REV:
137 case GL_UNSIGNED_INT_24_8:
138 case GL_UNSIGNED_INT_2_10_10_10_REV:
139 case GL_UNSIGNED_INT_5_9_9_9_REV:
140 case GL_UNSIGNED_SHORT:
141 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
142 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
143 return context->getClientVersion() >= ES_3_0;
144
145 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400146 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
147 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400148
149 case GL_HALF_FLOAT:
150 return context->getClientVersion() >= ES_3_0 ||
151 context->getExtensions().textureHalfFloat;
152
153 case GL_HALF_FLOAT_OES:
154 return context->getExtensions().colorBufferHalfFloat;
155
156 default:
157 return false;
158 }
159}
160
Jamie Madill5b772312018-03-08 20:28:32 -0500161bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400162{
163 switch (format)
164 {
165 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
166 case GL_RGBA:
167 case GL_RGB:
168 case GL_ALPHA:
169 return context->getClientVersion() >= ES_2_0;
170
171 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
172 case GL_RG:
173 case GL_RED:
174 case GL_RGBA_INTEGER:
175 case GL_RGB_INTEGER:
176 case GL_RG_INTEGER:
177 case GL_RED_INTEGER:
178 return context->getClientVersion() >= ES_3_0;
179
180 case GL_SRGB_ALPHA_EXT:
181 case GL_SRGB_EXT:
182 return context->getExtensions().sRGB;
183
184 case GL_BGRA_EXT:
185 return context->getExtensions().readFormatBGRA;
186
187 default:
188 return false;
189 }
190}
191
Jamie Madill5b772312018-03-08 20:28:32 -0500192bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400193 GLenum framebufferComponentType,
194 GLenum format,
195 GLenum type)
196{
197 switch (framebufferComponentType)
198 {
199 case GL_UNSIGNED_NORMALIZED:
200 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
201 // ReadPixels with BGRA even if the extension is not present
202 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
203 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
204 type == GL_UNSIGNED_BYTE);
205
206 case GL_SIGNED_NORMALIZED:
207 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
208
209 case GL_INT:
210 return (format == GL_RGBA_INTEGER && type == GL_INT);
211
212 case GL_UNSIGNED_INT:
213 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
214
215 case GL_FLOAT:
216 return (format == GL_RGBA && type == GL_FLOAT);
217
218 default:
219 UNREACHABLE();
220 return false;
221 }
222}
223
Geoff Langc1984ed2016-10-07 12:41:00 -0400224template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400225bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400226{
227 switch (ConvertToGLenum(params[0]))
228 {
229 case GL_CLAMP_TO_EDGE:
230 break;
231
Till Rathmannb8543632018-10-02 19:46:14 +0200232 case GL_CLAMP_TO_BORDER:
233 if (!context->getExtensions().textureBorderClamp)
234 {
Jamie Madill610640f2018-11-21 17:28:41 -0500235 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +0200236 return false;
237 }
238 break;
239
Geoff Langc1984ed2016-10-07 12:41:00 -0400240 case GL_REPEAT:
241 case GL_MIRRORED_REPEAT:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400242 if (restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400243 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400244 // OES_EGL_image_external and ANGLE_texture_rectangle specifies this error.
Jamie Madill610640f2018-11-21 17:28:41 -0500245 context->validationError(GL_INVALID_ENUM, kErrorInvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400246 return false;
247 }
248 break;
249
250 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500251 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureWrap);
Geoff Langc1984ed2016-10-07 12:41:00 -0400252 return false;
253 }
254
255 return true;
256}
257
258template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400259bool ValidateTextureMinFilterValue(Context *context, ParamType *params, bool restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400260{
261 switch (ConvertToGLenum(params[0]))
262 {
263 case GL_NEAREST:
264 case GL_LINEAR:
265 break;
266
267 case GL_NEAREST_MIPMAP_NEAREST:
268 case GL_LINEAR_MIPMAP_NEAREST:
269 case GL_NEAREST_MIPMAP_LINEAR:
270 case GL_LINEAR_MIPMAP_LINEAR:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400271 if (restrictedMinFilter)
Geoff Langc1984ed2016-10-07 12:41:00 -0400272 {
273 // OES_EGL_image_external specifies this error.
Jamie Madill610640f2018-11-21 17:28:41 -0500274 context->validationError(GL_INVALID_ENUM, kErrorInvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400275 return false;
276 }
277 break;
278
279 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500280 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400281 return false;
282 }
283
284 return true;
285}
286
287template <typename ParamType>
288bool ValidateTextureMagFilterValue(Context *context, ParamType *params)
289{
290 switch (ConvertToGLenum(params[0]))
291 {
292 case GL_NEAREST:
293 case GL_LINEAR:
294 break;
295
296 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500297 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureFilterParam);
Geoff Langc1984ed2016-10-07 12:41:00 -0400298 return false;
299 }
300
301 return true;
302}
303
304template <typename ParamType>
305bool ValidateTextureCompareModeValue(Context *context, ParamType *params)
306{
307 // Acceptable mode parameters from GLES 3.0.2 spec, table 3.17
308 switch (ConvertToGLenum(params[0]))
309 {
310 case GL_NONE:
311 case GL_COMPARE_REF_TO_TEXTURE:
312 break;
313
314 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500315 context->validationError(GL_INVALID_ENUM, kErrorUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400316 return false;
317 }
318
319 return true;
320}
321
322template <typename ParamType>
323bool ValidateTextureCompareFuncValue(Context *context, ParamType *params)
324{
325 // Acceptable function parameters from GLES 3.0.2 spec, table 3.17
326 switch (ConvertToGLenum(params[0]))
327 {
328 case GL_LEQUAL:
329 case GL_GEQUAL:
330 case GL_LESS:
331 case GL_GREATER:
332 case GL_EQUAL:
333 case GL_NOTEQUAL:
334 case GL_ALWAYS:
335 case GL_NEVER:
336 break;
337
338 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500339 context->validationError(GL_INVALID_ENUM, kErrorUnknownParameter);
Geoff Langc1984ed2016-10-07 12:41:00 -0400340 return false;
341 }
342
343 return true;
344}
345
346template <typename ParamType>
Geoff Lang81c6b572016-10-19 14:07:52 -0700347bool ValidateTextureSRGBDecodeValue(Context *context, ParamType *params)
348{
349 if (!context->getExtensions().textureSRGBDecode)
350 {
Jamie Madill610640f2018-11-21 17:28:41 -0500351 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Geoff Lang81c6b572016-10-19 14:07:52 -0700352 return false;
353 }
354
355 switch (ConvertToGLenum(params[0]))
356 {
357 case GL_DECODE_EXT:
358 case GL_SKIP_DECODE_EXT:
359 break;
360
361 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500362 context->validationError(GL_INVALID_ENUM, kErrorUnknownParameter);
Geoff Lang81c6b572016-10-19 14:07:52 -0700363 return false;
364 }
365
366 return true;
367}
368
Luc Ferron1b1a8642018-01-23 15:12:01 -0500369bool ValidateTextureMaxAnisotropyExtensionEnabled(Context *context)
370{
371 if (!context->getExtensions().textureFilterAnisotropic)
372 {
Jamie Madill610640f2018-11-21 17:28:41 -0500373 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500374 return false;
375 }
376
377 return true;
378}
379
380bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
381{
382 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
383 {
384 return false;
385 }
386
387 GLfloat largest = context->getExtensions().maxTextureAnisotropy;
388
389 if (paramValue < 1 || paramValue > largest)
390 {
Jamie Madill610640f2018-11-21 17:28:41 -0500391 context->validationError(GL_INVALID_VALUE, kErrorOutsideOfBounds);
Luc Ferron1b1a8642018-01-23 15:12:01 -0500392 return false;
393 }
394
395 return true;
396}
397
Jamie Madill5b772312018-03-08 20:28:32 -0500398bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
Geoff Lange0cff192017-05-30 13:04:56 -0400399{
Jamie Madill785e8a02018-10-04 17:42:00 -0400400 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lange0cff192017-05-30 13:04:56 -0400401 const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
402
Jamie Madille7d80f32018-08-08 15:49:23 -0400403 return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
404 framebuffer->getDrawBufferTypeMask().to_ulong(),
405 program->getActiveOutputVariables().to_ulong(),
406 framebuffer->getDrawBufferMask().to_ulong());
Geoff Lange0cff192017-05-30 13:04:56 -0400407}
408
Jamie Madill5b772312018-03-08 20:28:32 -0500409bool ValidateVertexShaderAttributeTypeMatch(Context *context)
Geoff Lang9ab5b822017-05-30 16:19:23 -0400410{
Lingfeng Yang038dd532018-03-29 17:31:52 -0700411 const auto &glState = context->getGLState();
Jamie Madill785e8a02018-10-04 17:42:00 -0400412 const Program *program = context->getGLState().getLinkedProgram(context);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400413 const VertexArray *vao = context->getGLState().getVertexArray();
414
Brandon Jonesc405ae72017-12-06 14:15:03 -0800415 unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
416 unsigned long vaoAttribTypeBits = vao->getAttributesTypeMask().to_ulong();
417 unsigned long vaoAttribEnabledMask = vao->getAttributesMask().to_ulong();
418
419 vaoAttribEnabledMask |= vaoAttribEnabledMask << MAX_COMPONENT_TYPE_MASK_INDEX;
420 vaoAttribTypeBits = (vaoAttribEnabledMask & vaoAttribTypeBits);
421 vaoAttribTypeBits |= (~vaoAttribEnabledMask & stateCurrentValuesTypeBits);
422
Jamie Madille7d80f32018-08-08 15:49:23 -0400423 return ComponentTypeMask::Validate(program->getAttributesTypeMask().to_ulong(),
424 vaoAttribTypeBits, program->getAttributesMask().to_ulong(),
425 0xFFFF);
Geoff Lang9ab5b822017-05-30 16:19:23 -0400426}
427
Jamie Madill493f9572018-05-24 19:52:15 -0400428bool IsCompatibleDrawModeWithGeometryShader(PrimitiveMode drawMode,
429 PrimitiveMode geometryShaderInputPrimitiveType)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800430{
431 // [EXT_geometry_shader] Section 11.1gs.1, Geometry Shader Input Primitives
Jamie Madill493f9572018-05-24 19:52:15 -0400432 switch (drawMode)
Jiawei Shaofccebff2018-03-08 13:51:02 +0800433 {
Jamie Madill493f9572018-05-24 19:52:15 -0400434 case PrimitiveMode::Points:
435 return geometryShaderInputPrimitiveType == PrimitiveMode::Points;
436 case PrimitiveMode::Lines:
437 case PrimitiveMode::LineStrip:
438 case PrimitiveMode::LineLoop:
439 return geometryShaderInputPrimitiveType == PrimitiveMode::Lines;
440 case PrimitiveMode::LinesAdjacency:
441 case PrimitiveMode::LineStripAdjacency:
442 return geometryShaderInputPrimitiveType == PrimitiveMode::LinesAdjacency;
443 case PrimitiveMode::Triangles:
444 case PrimitiveMode::TriangleFan:
445 case PrimitiveMode::TriangleStrip:
446 return geometryShaderInputPrimitiveType == PrimitiveMode::Triangles;
447 case PrimitiveMode::TrianglesAdjacency:
448 case PrimitiveMode::TriangleStripAdjacency:
449 return geometryShaderInputPrimitiveType == PrimitiveMode::TrianglesAdjacency;
Jiawei Shaofccebff2018-03-08 13:51:02 +0800450 default:
451 UNREACHABLE();
452 return false;
453 }
454}
455
Lingfeng Yangf97641c2018-06-21 19:22:45 -0700456// GLES1 texture parameters are a small subset of the others
457bool IsValidGLES1TextureParameter(GLenum pname)
458{
459 switch (pname)
460 {
461 case GL_TEXTURE_MAG_FILTER:
462 case GL_TEXTURE_MIN_FILTER:
463 case GL_TEXTURE_WRAP_S:
464 case GL_TEXTURE_WRAP_T:
465 case GL_TEXTURE_WRAP_R:
466 case GL_GENERATE_MIPMAP:
467 case GL_TEXTURE_CROP_RECT_OES:
468 return true;
469 default:
470 return false;
471 }
472}
Till Rathmannb8543632018-10-02 19:46:14 +0200473
474unsigned int GetSamplerParameterCount(GLenum pname)
475{
476 return pname == GL_TEXTURE_BORDER_COLOR ? 4 : 1;
477}
478
Geoff Langf41a7152016-09-19 15:11:17 -0400479} // anonymous namespace
480
Brandon Jonesd1049182018-03-28 10:02:20 -0700481void SetRobustLengthParam(GLsizei *length, GLsizei value)
482{
483 if (length)
484 {
485 *length = value;
486 }
487}
488
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500489bool IsETC2EACFormat(const GLenum format)
490{
491 // ES 3.1, Table 8.19
492 switch (format)
493 {
494 case GL_COMPRESSED_R11_EAC:
495 case GL_COMPRESSED_SIGNED_R11_EAC:
496 case GL_COMPRESSED_RG11_EAC:
497 case GL_COMPRESSED_SIGNED_RG11_EAC:
498 case GL_COMPRESSED_RGB8_ETC2:
499 case GL_COMPRESSED_SRGB8_ETC2:
500 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
501 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
502 case GL_COMPRESSED_RGBA8_ETC2_EAC:
503 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
504 return true;
505
506 default:
507 return false;
508 }
509}
510
Jamie Madill5b772312018-03-08 20:28:32 -0500511bool ValidTextureTarget(const Context *context, TextureType type)
Jamie Madill35d15012013-10-07 10:46:37 -0400512{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800513 switch (type)
Jamie Madill35d15012013-10-07 10:46:37 -0400514 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800515 case TextureType::_2D:
516 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800517 return true;
Jamie Madill35d15012013-10-07 10:46:37 -0400518
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800519 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400520 return context->getExtensions().textureRectangle;
521
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800522 case TextureType::_3D:
523 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800524 return (context->getClientMajorVersion() >= 3);
Jamie Madilld7460c72014-01-21 16:38:14 -0500525
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800526 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +0800527 return (context->getClientVersion() >= Version(3, 1) ||
528 context->getExtensions().textureMultisample);
Olli Etuahod310a432018-08-24 15:40:23 +0300529 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300530 return context->getExtensions().textureStorageMultisample2DArray;
Geoff Lang3b573612016-10-31 14:08:10 -0400531
He Yunchaoced53ae2016-11-29 15:00:51 +0800532 default:
533 return false;
Jamie Madilld7460c72014-01-21 16:38:14 -0500534 }
Jamie Madill35d15012013-10-07 10:46:37 -0400535}
536
Jamie Madill5b772312018-03-08 20:28:32 -0500537bool ValidTexture2DTarget(const Context *context, TextureType type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500538{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800539 switch (type)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500540 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800541 case TextureType::_2D:
542 case TextureType::CubeMap:
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500543 return true;
544
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800545 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400546 return context->getExtensions().textureRectangle;
547
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500548 default:
549 return false;
550 }
551}
552
Jamie Madill5b772312018-03-08 20:28:32 -0500553bool ValidTexture3DTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500554{
555 switch (target)
556 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800557 case TextureType::_3D:
558 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +0300559 return (context->getClientMajorVersion() >= 3);
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500560
561 default:
562 return false;
563 }
564}
565
Ian Ewellbda75592016-04-18 17:25:54 -0400566// Most texture GL calls are not compatible with external textures, so we have a separate validation
567// function for use in the GL calls that do
Jamie Madill5b772312018-03-08 20:28:32 -0500568bool ValidTextureExternalTarget(const Context *context, TextureType target)
Ian Ewellbda75592016-04-18 17:25:54 -0400569{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800570 return (target == TextureType::External) &&
Ian Ewellbda75592016-04-18 17:25:54 -0400571 (context->getExtensions().eglImageExternal ||
572 context->getExtensions().eglStreamConsumerExternal);
573}
574
Shannon Woods4dfed832014-03-17 20:03:39 -0400575// This function differs from ValidTextureTarget in that the target must be
576// usable as the destination of a 2D operation-- so a cube face is valid, but
577// GL_TEXTURE_CUBE_MAP is not.
Jamie Madill560a8d82014-05-21 13:06:20 -0400578// Note: duplicate of IsInternalTextureTarget
Jamie Madill5b772312018-03-08 20:28:32 -0500579bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target)
Shannon Woods4dfed832014-03-17 20:03:39 -0400580{
581 switch (target)
582 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800583 case TextureTarget::_2D:
584 case TextureTarget::CubeMapNegativeX:
585 case TextureTarget::CubeMapNegativeY:
586 case TextureTarget::CubeMapNegativeZ:
587 case TextureTarget::CubeMapPositiveX:
588 case TextureTarget::CubeMapPositiveY:
589 case TextureTarget::CubeMapPositiveZ:
He Yunchaoced53ae2016-11-29 15:00:51 +0800590 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800591 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400592 return context->getExtensions().textureRectangle;
He Yunchaoced53ae2016-11-29 15:00:51 +0800593 default:
594 return false;
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500595 }
596}
597
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800598bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400599 PrimitiveMode transformFeedbackPrimitiveMode,
600 PrimitiveMode renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800601{
602 ASSERT(context);
603
604 if (!context->getExtensions().geometryShader)
605 {
606 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode
607 // that does not match the current transform feedback object's draw mode (if transform
608 // feedback is active), (3.0.2, section 2.14, pg 86)
609 return transformFeedbackPrimitiveMode == renderPrimitiveMode;
610 }
611
612 // [GL_EXT_geometry_shader] Table 12.1gs
Jamie Madill493f9572018-05-24 19:52:15 -0400613 switch (renderPrimitiveMode)
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800614 {
Jamie Madill493f9572018-05-24 19:52:15 -0400615 case PrimitiveMode::Points:
616 return transformFeedbackPrimitiveMode == PrimitiveMode::Points;
617 case PrimitiveMode::Lines:
618 case PrimitiveMode::LineStrip:
619 case PrimitiveMode::LineLoop:
620 return transformFeedbackPrimitiveMode == PrimitiveMode::Lines;
621 case PrimitiveMode::Triangles:
622 case PrimitiveMode::TriangleFan:
623 case PrimitiveMode::TriangleStrip:
624 return transformFeedbackPrimitiveMode == PrimitiveMode::Triangles;
Jiawei Shao80c32cc2018-04-25 09:48:36 +0800625 default:
626 UNREACHABLE();
627 return false;
628 }
629}
630
Jamie Madill5b772312018-03-08 20:28:32 -0500631bool ValidateDrawElementsInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400632 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400633 GLsizei count,
634 GLenum type,
635 const GLvoid *indices,
636 GLsizei primcount)
637{
638 if (primcount < 0)
639 {
Jamie Madill610640f2018-11-21 17:28:41 -0500640 context->validationError(GL_INVALID_VALUE, kErrorNegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400641 return false;
642 }
643
644 if (!ValidateDrawElementsCommon(context, mode, count, type, indices, primcount))
645 {
646 return false;
647 }
648
Jamie Madill9fdaa492018-02-16 10:52:11 -0500649 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400650}
651
652bool ValidateDrawArraysInstancedBase(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -0400653 PrimitiveMode mode,
Jamie Madillbe849e42017-05-02 15:49:00 -0400654 GLint first,
655 GLsizei count,
656 GLsizei primcount)
657{
658 if (primcount < 0)
659 {
Jamie Madill610640f2018-11-21 17:28:41 -0500660 context->validationError(GL_INVALID_VALUE, kErrorNegativePrimcount);
Jamie Madillbe849e42017-05-02 15:49:00 -0400661 return false;
662 }
663
664 if (!ValidateDrawArraysCommon(context, mode, first, count, primcount))
665 {
666 return false;
667 }
668
Jamie Madill9fdaa492018-02-16 10:52:11 -0500669 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -0400670}
671
Jamie Madill5b772312018-03-08 20:28:32 -0500672bool ValidateDrawInstancedANGLE(Context *context)
Jamie Madillbe849e42017-05-02 15:49:00 -0400673{
674 // Verify there is at least one active attribute with a divisor of zero
675 const State &state = context->getGLState();
676
Jamie Madill785e8a02018-10-04 17:42:00 -0400677 Program *program = state.getLinkedProgram(context);
Jamie Madillbe849e42017-05-02 15:49:00 -0400678
679 const auto &attribs = state.getVertexArray()->getVertexAttributes();
680 const auto &bindings = state.getVertexArray()->getVertexBindings();
681 for (size_t attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
682 {
683 const VertexAttribute &attrib = attribs[attributeIndex];
684 const VertexBinding &binding = bindings[attrib.bindingIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +0300685 if (program->isAttribLocationActive(attributeIndex) && binding.getDivisor() == 0)
Jamie Madillbe849e42017-05-02 15:49:00 -0400686 {
687 return true;
688 }
689 }
690
Jamie Madill610640f2018-11-21 17:28:41 -0500691 context->validationError(GL_INVALID_OPERATION, kErrorNoZeroDivisor);
Jamie Madillbe849e42017-05-02 15:49:00 -0400692 return false;
693}
694
Jamie Madill5b772312018-03-08 20:28:32 -0500695bool ValidTexture3DDestinationTarget(const Context *context, TextureType target)
Ian Ewellfc7cf8e2016-01-20 15:57:46 -0500696{
697 switch (target)
698 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800699 case TextureType::_3D:
700 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +0800701 return true;
702 default:
703 return false;
Shannon Woods4dfed832014-03-17 20:03:39 -0400704 }
705}
706
Jamie Madill5b772312018-03-08 20:28:32 -0500707bool ValidTexLevelDestinationTarget(const Context *context, TextureType type)
He Yunchao11b038b2016-11-22 21:24:04 +0800708{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800709 switch (type)
He Yunchao11b038b2016-11-22 21:24:04 +0800710 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800711 case TextureType::_2D:
712 case TextureType::_2DArray:
713 case TextureType::_2DMultisample:
714 case TextureType::CubeMap:
715 case TextureType::_3D:
He Yunchao11b038b2016-11-22 21:24:04 +0800716 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800717 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400718 return context->getExtensions().textureRectangle;
Olli Etuahod310a432018-08-24 15:40:23 +0300719 case TextureType::_2DMultisampleArray:
Olli Etuaho064458a2018-08-30 14:02:02 +0300720 return context->getExtensions().textureStorageMultisample2DArray;
He Yunchao11b038b2016-11-22 21:24:04 +0800721 default:
722 return false;
723 }
724}
725
Jamie Madill5b772312018-03-08 20:28:32 -0500726bool ValidFramebufferTarget(const Context *context, GLenum target)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500727{
He Yunchaoced53ae2016-11-29 15:00:51 +0800728 static_assert(GL_DRAW_FRAMEBUFFER_ANGLE == GL_DRAW_FRAMEBUFFER &&
729 GL_READ_FRAMEBUFFER_ANGLE == GL_READ_FRAMEBUFFER,
Geoff Langd4475812015-03-18 10:53:05 -0400730 "ANGLE framebuffer enums must equal the ES3 framebuffer enums.");
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500731
732 switch (target)
733 {
He Yunchaoced53ae2016-11-29 15:00:51 +0800734 case GL_FRAMEBUFFER:
735 return true;
Geoff Lange8afa902017-09-27 15:00:43 -0400736
He Yunchaoced53ae2016-11-29 15:00:51 +0800737 case GL_READ_FRAMEBUFFER:
He Yunchaoced53ae2016-11-29 15:00:51 +0800738 case GL_DRAW_FRAMEBUFFER:
Geoff Lange8afa902017-09-27 15:00:43 -0400739 return (context->getExtensions().framebufferBlit ||
740 context->getClientMajorVersion() >= 3);
741
He Yunchaoced53ae2016-11-29 15:00:51 +0800742 default:
743 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -0500744 }
745}
746
Jamie Madill5b772312018-03-08 20:28:32 -0500747bool ValidMipLevel(const Context *context, TextureType type, GLint level)
Geoff Langce635692013-09-24 13:56:32 -0400748{
Jamie Madillc29968b2016-01-20 11:17:23 -0500749 const auto &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -0400750 size_t maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800751 switch (type)
Geoff Langce635692013-09-24 13:56:32 -0400752 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800753 case TextureType::_2D:
754 case TextureType::_2DArray:
755 case TextureType::_2DMultisample:
Olli Etuahod310a432018-08-24 15:40:23 +0300756 case TextureType::_2DMultisampleArray:
757 // TODO(http://anglebug.com/2775): It's a bit unclear what the "maximum allowable
758 // level-of-detail" for multisample textures should be. Could maybe make it zero.
Jamie Madillc29968b2016-01-20 11:17:23 -0500759 maxDimension = caps.max2DTextureSize;
760 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800761 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +0800762 maxDimension = caps.maxCubeMapTextureSize;
763 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800764 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400765 return level == 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800766 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +0800767 maxDimension = caps.max3DTextureSize;
768 break;
He Yunchaoced53ae2016-11-29 15:00:51 +0800769 default:
770 UNREACHABLE();
Geoff Langce635692013-09-24 13:56:32 -0400771 }
772
Jamie Madill43da7c42018-08-01 11:34:49 -0400773 return level <= log2(static_cast<int>(maxDimension)) && level >= 0;
Geoff Langce635692013-09-24 13:56:32 -0400774}
775
Jamie Madill5b772312018-03-08 20:28:32 -0500776bool ValidImageSizeParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800777 TextureType target,
Austin Kinross08528e12015-10-07 16:24:40 -0700778 GLint level,
779 GLsizei width,
780 GLsizei height,
781 GLsizei depth,
782 bool isSubImage)
Geoff Langce635692013-09-24 13:56:32 -0400783{
Brandon Jones6cad5662017-06-14 13:25:13 -0700784 if (width < 0 || height < 0 || depth < 0)
Geoff Langce635692013-09-24 13:56:32 -0400785 {
Jamie Madill610640f2018-11-21 17:28:41 -0500786 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Geoff Langce635692013-09-24 13:56:32 -0400787 return false;
788 }
Austin Kinross08528e12015-10-07 16:24:40 -0700789 // TexSubImage parameters can be NPOT without textureNPOT extension,
790 // as long as the destination texture is POT.
Geoff Langcc507aa2016-12-12 10:09:52 -0500791 bool hasNPOTSupport =
Geoff Lang5f319a42017-01-09 16:49:19 -0500792 context->getExtensions().textureNPOT || context->getClientVersion() >= Version(3, 0);
Geoff Langcc507aa2016-12-12 10:09:52 -0500793 if (!isSubImage && !hasNPOTSupport &&
Jamie Madill43da7c42018-08-01 11:34:49 -0400794 (level != 0 && (!isPow2(width) || !isPow2(height) || !isPow2(depth))))
Geoff Langce635692013-09-24 13:56:32 -0400795 {
Jamie Madill610640f2018-11-21 17:28:41 -0500796 context->validationError(GL_INVALID_VALUE, kErrorTextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400797 return false;
798 }
799
800 if (!ValidMipLevel(context, target, level))
801 {
Jamie Madill610640f2018-11-21 17:28:41 -0500802 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Geoff Langce635692013-09-24 13:56:32 -0400803 return false;
804 }
805
806 return true;
807}
808
Geoff Lang966c9402017-04-18 12:38:27 -0400809bool ValidCompressedDimension(GLsizei size, GLuint blockSize, bool smallerThanBlockSizeAllowed)
810{
811 return (smallerThanBlockSizeAllowed && (size > 0) && (blockSize % size == 0)) ||
812 (size % blockSize == 0);
813}
814
Jamie Madill5b772312018-03-08 20:28:32 -0500815bool ValidCompressedImageSize(const Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -0500816 GLenum internalFormat,
Geoff Lang966c9402017-04-18 12:38:27 -0400817 GLint level,
Jamie Madillc29968b2016-01-20 11:17:23 -0500818 GLsizei width,
819 GLsizei height)
Geoff Langd4f180b2013-09-24 13:57:44 -0400820{
Jamie Madill43da7c42018-08-01 11:34:49 -0400821 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang5d601382014-07-22 15:14:06 -0400822 if (!formatInfo.compressed)
Geoff Langd4f180b2013-09-24 13:57:44 -0400823 {
824 return false;
825 }
826
Geoff Lang966c9402017-04-18 12:38:27 -0400827 if (width < 0 || height < 0)
828 {
829 return false;
830 }
831
832 if (CompressedTextureFormatRequiresExactSize(internalFormat))
833 {
834 // The ANGLE extensions allow specifying compressed textures with sizes smaller than the
835 // block size for level 0 but WebGL disallows this.
836 bool smallerThanBlockSizeAllowed =
837 level > 0 || !context->getExtensions().webglCompatibility;
838
839 if (!ValidCompressedDimension(width, formatInfo.compressedBlockWidth,
840 smallerThanBlockSizeAllowed) ||
841 !ValidCompressedDimension(height, formatInfo.compressedBlockHeight,
842 smallerThanBlockSizeAllowed))
843 {
844 return false;
845 }
846 }
847
848 return true;
849}
850
Jamie Madill5b772312018-03-08 20:28:32 -0500851bool ValidCompressedSubImageSize(const Context *context,
Geoff Lang966c9402017-04-18 12:38:27 -0400852 GLenum internalFormat,
853 GLint xoffset,
854 GLint yoffset,
855 GLsizei width,
856 GLsizei height,
857 size_t textureWidth,
858 size_t textureHeight)
859{
Jamie Madill43da7c42018-08-01 11:34:49 -0400860 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
Geoff Lang966c9402017-04-18 12:38:27 -0400861 if (!formatInfo.compressed)
862 {
863 return false;
864 }
865
Geoff Lang44ff5a72017-02-03 15:15:43 -0500866 if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
Geoff Langd4f180b2013-09-24 13:57:44 -0400867 {
868 return false;
869 }
870
Luc Ferron9dbaeba2018-02-01 07:26:59 -0500871 if (CompressedSubTextureFormatRequiresExactSize(internalFormat))
Geoff Lang0d8b7242015-09-09 14:56:53 -0400872 {
Geoff Lang44ff5a72017-02-03 15:15:43 -0500873 if (xoffset % formatInfo.compressedBlockWidth != 0 ||
Geoff Lang966c9402017-04-18 12:38:27 -0400874 yoffset % formatInfo.compressedBlockHeight != 0)
875 {
876 return false;
877 }
878
879 // Allowed to either have data that is a multiple of block size or is smaller than the block
880 // size but fills the entire mip
881 bool fillsEntireMip = xoffset == 0 && yoffset == 0 &&
882 static_cast<size_t>(width) == textureWidth &&
883 static_cast<size_t>(height) == textureHeight;
884 bool sizeMultipleOfBlockSize = (width % formatInfo.compressedBlockWidth) == 0 &&
885 (height % formatInfo.compressedBlockHeight) == 0;
886 if (!sizeMultipleOfBlockSize && !fillsEntireMip)
Geoff Lang0d8b7242015-09-09 14:56:53 -0400887 {
888 return false;
889 }
890 }
891
Geoff Langd4f180b2013-09-24 13:57:44 -0400892 return true;
893}
894
Jamie Madill5b772312018-03-08 20:28:32 -0500895bool ValidImageDataSize(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800896 TextureType texType,
Geoff Langff5b2d52016-09-07 11:32:23 -0400897 GLsizei width,
898 GLsizei height,
899 GLsizei depth,
Geoff Langdbcced82017-06-06 15:55:54 -0400900 GLenum format,
Geoff Langff5b2d52016-09-07 11:32:23 -0400901 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -0400902 const void *pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -0400903 GLsizei imageSize)
904{
Jamie Madill43da7c42018-08-01 11:34:49 -0400905 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Geoff Langff5b2d52016-09-07 11:32:23 -0400906 if (pixelUnpackBuffer == nullptr && imageSize < 0)
907 {
908 // Checks are not required
909 return true;
910 }
911
912 // ...the data would be unpacked from the buffer object such that the memory reads required
913 // would exceed the data store size.
Jamie Madill43da7c42018-08-01 11:34:49 -0400914 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Geoff Langdbcced82017-06-06 15:55:54 -0400915 ASSERT(formatInfo.internalFormat != GL_NONE);
Jamie Madill43da7c42018-08-01 11:34:49 -0400916 const Extents size(width, height, depth);
Geoff Langff5b2d52016-09-07 11:32:23 -0400917 const auto &unpack = context->getGLState().getUnpackState();
918
Jamie Madill7f232932018-09-12 11:03:06 -0400919 bool targetIs3D = texType == TextureType::_3D || texType == TextureType::_2DArray;
920 GLuint endByte = 0;
Jamie Madillca2ff382018-07-11 09:01:17 -0400921 if (!formatInfo.computePackUnpackEndByte(type, size, unpack, targetIs3D, &endByte))
Geoff Langff5b2d52016-09-07 11:32:23 -0400922 {
Jamie Madill610640f2018-11-21 17:28:41 -0500923 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400924 return false;
925 }
926
Geoff Langff5b2d52016-09-07 11:32:23 -0400927 if (pixelUnpackBuffer)
928 {
Jamie Madillca2ff382018-07-11 09:01:17 -0400929 CheckedNumeric<size_t> checkedEndByte(endByte);
Geoff Langff5b2d52016-09-07 11:32:23 -0400930 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
931 checkedEndByte += checkedOffset;
932
933 if (!checkedEndByte.IsValid() ||
934 (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelUnpackBuffer->getSize())))
935 {
936 // Overflow past the end of the buffer
Jamie Madill610640f2018-11-21 17:28:41 -0500937 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Geoff Langff5b2d52016-09-07 11:32:23 -0400938 return false;
939 }
James Darpiniane8a93c62018-01-04 18:02:24 -0800940 if (context->getExtensions().webglCompatibility &&
941 pixelUnpackBuffer->isBoundForTransformFeedbackAndOtherUse())
942 {
Jamie Madill610640f2018-11-21 17:28:41 -0500943 context->validationError(GL_INVALID_OPERATION,
944 kErrorPixelUnpackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -0800945 return false;
946 }
Geoff Langff5b2d52016-09-07 11:32:23 -0400947 }
948 else
949 {
950 ASSERT(imageSize >= 0);
951 if (pixels == nullptr && imageSize != 0)
952 {
Jamie Madill610640f2018-11-21 17:28:41 -0500953 context->validationError(GL_INVALID_OPERATION,
954 "imageSize must be 0 if no texture data is provided.");
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400955 return false;
Geoff Langff5b2d52016-09-07 11:32:23 -0400956 }
957
Geoff Lang3feb3ff2016-10-26 10:57:45 -0400958 if (pixels != nullptr && endByte > static_cast<GLuint>(imageSize))
Geoff Langff5b2d52016-09-07 11:32:23 -0400959 {
Jamie Madill610640f2018-11-21 17:28:41 -0500960 context->validationError(GL_INVALID_OPERATION, "imageSize is too small");
Geoff Langff5b2d52016-09-07 11:32:23 -0400961 return false;
962 }
963 }
964
965 return true;
966}
967
Corentin Wallezad3ae902018-03-09 13:40:42 -0500968bool ValidQueryType(const Context *context, QueryType queryType)
Geoff Lang37dde692014-01-31 16:34:54 -0500969{
Geoff Lang37dde692014-01-31 16:34:54 -0500970 switch (queryType)
971 {
Corentin Wallezad3ae902018-03-09 13:40:42 -0500972 case QueryType::AnySamples:
973 case QueryType::AnySamplesConservative:
Geoff Lang8c5b31c2017-09-26 18:07:44 -0400974 return context->getClientMajorVersion() >= 3 ||
975 context->getExtensions().occlusionQueryBoolean;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500976 case QueryType::TransformFeedbackPrimitivesWritten:
He Yunchaoced53ae2016-11-29 15:00:51 +0800977 return (context->getClientMajorVersion() >= 3);
Corentin Wallezad3ae902018-03-09 13:40:42 -0500978 case QueryType::TimeElapsed:
He Yunchaoced53ae2016-11-29 15:00:51 +0800979 return context->getExtensions().disjointTimerQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500980 case QueryType::CommandsCompleted:
He Yunchaoced53ae2016-11-29 15:00:51 +0800981 return context->getExtensions().syncQuery;
Corentin Wallezad3ae902018-03-09 13:40:42 -0500982 case QueryType::PrimitivesGenerated:
Jiawei Shaod2fa07e2018-03-15 09:20:25 +0800983 return context->getExtensions().geometryShader;
He Yunchaoced53ae2016-11-29 15:00:51 +0800984 default:
985 return false;
Geoff Lang37dde692014-01-31 16:34:54 -0500986 }
987}
988
Jamie Madill5b772312018-03-08 20:28:32 -0500989bool ValidateWebGLVertexAttribPointer(Context *context,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400990 GLenum type,
991 GLboolean normalized,
992 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -0400993 const void *ptr,
Geoff Lang2d62ab72017-03-23 16:54:40 -0400994 bool pureInteger)
995{
996 ASSERT(context->getExtensions().webglCompatibility);
Geoff Lang2d62ab72017-03-23 16:54:40 -0400997 // WebGL 1.0 [Section 6.11] Vertex Attribute Data Stride
998 // The WebGL API supports vertex attribute data strides up to 255 bytes. A call to
999 // vertexAttribPointer will generate an INVALID_VALUE error if the value for the stride
1000 // parameter exceeds 255.
1001 constexpr GLsizei kMaxWebGLStride = 255;
1002 if (stride > kMaxWebGLStride)
1003 {
Jamie Madill610640f2018-11-21 17:28:41 -05001004 context->validationError(GL_INVALID_VALUE,
1005 "Stride is over the maximum stride allowed by WebGL.");
Geoff Lang2d62ab72017-03-23 16:54:40 -04001006 return false;
1007 }
1008
1009 // WebGL 1.0 [Section 6.4] Buffer Offset and Stride Requirements
1010 // The offset arguments to drawElements and vertexAttribPointer, and the stride argument to
1011 // vertexAttribPointer, must be a multiple of the size of the data type passed to the call,
1012 // or an INVALID_OPERATION error is generated.
Frank Henigmand633b152018-10-04 23:34:31 -04001013 angle::FormatID internalType = GetVertexFormatID(type, normalized, 1, pureInteger);
1014 size_t typeSize = GetVertexFormatSize(internalType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001015
1016 ASSERT(isPow2(typeSize) && typeSize > 0);
1017 size_t sizeMask = (typeSize - 1);
1018 if ((reinterpret_cast<intptr_t>(ptr) & sizeMask) != 0)
1019 {
Jamie Madill610640f2018-11-21 17:28:41 -05001020 context->validationError(GL_INVALID_OPERATION, kErrorOffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001021 return false;
1022 }
1023
1024 if ((stride & sizeMask) != 0)
1025 {
Jamie Madill610640f2018-11-21 17:28:41 -05001026 context->validationError(GL_INVALID_OPERATION, kErrorStrideMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001027 return false;
1028 }
1029
1030 return true;
1031}
1032
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001033Program *GetValidProgramNoResolve(Context *context, GLuint id)
Geoff Lang48dcae72014-02-05 16:28:24 -05001034{
He Yunchaoced53ae2016-11-29 15:00:51 +08001035 // ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
1036 // generate the error INVALID_VALUE if the provided name is not the name of either a shader
1037 // or program object and INVALID_OPERATION if the provided name identifies an object
1038 // that is not the expected type."
Geoff Lang48dcae72014-02-05 16:28:24 -05001039
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001040 Program *validProgram = context->getProgramNoResolveLink(id);
Dian Xiang769769a2015-09-09 15:20:08 -07001041
1042 if (!validProgram)
Geoff Lang48dcae72014-02-05 16:28:24 -05001043 {
Dian Xiang769769a2015-09-09 15:20:08 -07001044 if (context->getShader(id))
1045 {
Jamie Madill610640f2018-11-21 17:28:41 -05001046 context->validationError(GL_INVALID_OPERATION, kErrorExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001047 }
1048 else
1049 {
Jamie Madill610640f2018-11-21 17:28:41 -05001050 context->validationError(GL_INVALID_VALUE, kErrorInvalidProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001051 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001052 }
Dian Xiang769769a2015-09-09 15:20:08 -07001053
1054 return validProgram;
1055}
1056
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001057Program *GetValidProgram(Context *context, GLuint id)
1058{
1059 Program *program = GetValidProgramNoResolve(context, id);
1060 if (program)
1061 {
Jamie Madill785e8a02018-10-04 17:42:00 -04001062 program->resolveLink(context);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001063 }
1064 return program;
1065}
1066
Jamie Madill5b772312018-03-08 20:28:32 -05001067Shader *GetValidShader(Context *context, GLuint id)
Dian Xiang769769a2015-09-09 15:20:08 -07001068{
1069 // See ValidProgram for spec details.
1070
1071 Shader *validShader = context->getShader(id);
1072
1073 if (!validShader)
Geoff Lang48dcae72014-02-05 16:28:24 -05001074 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04001075 if (context->getProgramNoResolveLink(id))
Dian Xiang769769a2015-09-09 15:20:08 -07001076 {
Jamie Madill610640f2018-11-21 17:28:41 -05001077 context->validationError(GL_INVALID_OPERATION, kErrorExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001078 }
1079 else
1080 {
Jamie Madill610640f2018-11-21 17:28:41 -05001081 context->validationError(GL_INVALID_VALUE, kErrorInvalidShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001082 }
Geoff Lang48dcae72014-02-05 16:28:24 -05001083 }
Dian Xiang769769a2015-09-09 15:20:08 -07001084
1085 return validShader;
Geoff Lang48dcae72014-02-05 16:28:24 -05001086}
1087
Jamie Madill43da7c42018-08-01 11:34:49 -04001088bool ValidateAttachmentTarget(Context *context, GLenum attachment)
Jamie Madillb4472272014-07-03 10:38:55 -04001089{
Geoff Langfa125c92017-10-24 13:01:46 -04001090 if (attachment >= GL_COLOR_ATTACHMENT1_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
Jamie Madillb4472272014-07-03 10:38:55 -04001091 {
Geoff Langfa125c92017-10-24 13:01:46 -04001092 if (context->getClientMajorVersion() < 3 && !context->getExtensions().drawBuffers)
1093 {
Jamie Madill610640f2018-11-21 17:28:41 -05001094 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
Geoff Langfa125c92017-10-24 13:01:46 -04001095 return false;
1096 }
Jamie Madillb4472272014-07-03 10:38:55 -04001097
Geoff Langfa125c92017-10-24 13:01:46 -04001098 // Color attachment 0 is validated below because it is always valid
1099 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
Geoff Langaae65a42014-05-26 12:43:44 -04001100 if (colorAttachment >= context->getCaps().maxColorAttachments)
Jamie Madillb4472272014-07-03 10:38:55 -04001101 {
Jamie Madill610640f2018-11-21 17:28:41 -05001102 context->validationError(GL_INVALID_OPERATION, kErrorInvalidAttachment);
Geoff Langb1196682014-07-23 13:47:29 -04001103 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001104 }
1105 }
1106 else
1107 {
1108 switch (attachment)
1109 {
Geoff Langfa125c92017-10-24 13:01:46 -04001110 case GL_COLOR_ATTACHMENT0:
He Yunchaoced53ae2016-11-29 15:00:51 +08001111 case GL_DEPTH_ATTACHMENT:
1112 case GL_STENCIL_ATTACHMENT:
1113 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001114
He Yunchaoced53ae2016-11-29 15:00:51 +08001115 case GL_DEPTH_STENCIL_ATTACHMENT:
1116 if (!context->getExtensions().webglCompatibility &&
1117 context->getClientMajorVersion() < 3)
1118 {
Jamie Madill610640f2018-11-21 17:28:41 -05001119 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001120 return false;
1121 }
1122 break;
Jamie Madillb4472272014-07-03 10:38:55 -04001123
He Yunchaoced53ae2016-11-29 15:00:51 +08001124 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001125 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08001126 return false;
Jamie Madillb4472272014-07-03 10:38:55 -04001127 }
1128 }
1129
1130 return true;
1131}
1132
Jamie Madill5b772312018-03-08 20:28:32 -05001133bool ValidateRenderbufferStorageParametersBase(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001134 GLenum target,
1135 GLsizei samples,
1136 GLenum internalformat,
1137 GLsizei width,
1138 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001139{
1140 switch (target)
1141 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001142 case GL_RENDERBUFFER:
1143 break;
1144 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001145 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001146 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001147 }
1148
1149 if (width < 0 || height < 0 || samples < 0)
1150 {
Jamie Madill610640f2018-11-21 17:28:41 -05001151 context->validationError(GL_INVALID_VALUE, kErrorInvalidRenderbufferWidthHeight);
Geoff Langb1196682014-07-23 13:47:29 -04001152 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001153 }
1154
Jamie Madill4e0e6f82017-02-17 11:06:03 -05001155 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
1156 GLenum convertedInternalFormat = context->getConvertedRenderbufferFormat(internalformat);
1157
1158 const TextureCaps &formatCaps = context->getTextureCaps().get(convertedInternalFormat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04001159 if (!formatCaps.renderbuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001160 {
Jamie Madill610640f2018-11-21 17:28:41 -05001161 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001162 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001163 }
1164
1165 // ANGLE_framebuffer_multisample does not explicitly state that the internal format must be
1166 // 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 -08001167 // only sized internal formats.
Jamie Madill43da7c42018-08-01 11:34:49 -04001168 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(convertedInternalFormat);
Geoff Langca271392017-04-05 12:30:00 -04001169 if (formatInfo.internalFormat == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001170 {
Jamie Madill610640f2018-11-21 17:28:41 -05001171 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 }
1174
Geoff Langaae65a42014-05-26 12:43:44 -04001175 if (static_cast<GLuint>(std::max(width, height)) > context->getCaps().maxRenderbufferSize)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001176 {
Jamie Madill610640f2018-11-21 17:28:41 -05001177 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxRenderbufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04001178 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001179 }
1180
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001181 GLuint handle = context->getGLState().getRenderbufferId();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001182 if (handle == 0)
1183 {
Jamie Madill610640f2018-11-21 17:28:41 -05001184 context->validationError(GL_INVALID_OPERATION, kErrorInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001185 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 }
1187
1188 return true;
1189}
1190
Jamie Madill43da7c42018-08-01 11:34:49 -04001191bool ValidateFramebufferRenderbufferParameters(Context *context,
He Yunchaoced53ae2016-11-29 15:00:51 +08001192 GLenum target,
1193 GLenum attachment,
1194 GLenum renderbuffertarget,
1195 GLuint renderbuffer)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001196{
Geoff Lange8afa902017-09-27 15:00:43 -04001197 if (!ValidFramebufferTarget(context, target))
Shannon Woods1da3cf62014-06-27 15:32:23 -04001198 {
Jamie Madill610640f2018-11-21 17:28:41 -05001199 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001200 return false;
Shannon Woods1da3cf62014-06-27 15:32:23 -04001201 }
1202
Jamie Madill43da7c42018-08-01 11:34:49 -04001203 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001204
Jamie Madill84115c92015-04-23 15:00:07 -04001205 ASSERT(framebuffer);
1206 if (framebuffer->id() == 0)
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001207 {
Jamie Madill610640f2018-11-21 17:28:41 -05001208 context->validationError(GL_INVALID_OPERATION, kErrorDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001209 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001210 }
1211
Jamie Madillb4472272014-07-03 10:38:55 -04001212 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001213 {
Jamie Madillb4472272014-07-03 10:38:55 -04001214 return false;
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001215 }
1216
Jamie Madillab9d82c2014-01-21 16:38:14 -05001217 // [OpenGL ES 2.0.25] Section 4.4.3 page 112
1218 // [OpenGL ES 3.0.2] Section 4.4.2 page 201
1219 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of
1220 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.
1221 if (renderbuffer != 0)
1222 {
1223 if (!context->getRenderbuffer(renderbuffer))
1224 {
Jamie Madill610640f2018-11-21 17:28:41 -05001225 context->validationError(GL_INVALID_OPERATION, kErrorInvalidRenderbufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001226 return false;
Jamie Madillab9d82c2014-01-21 16:38:14 -05001227 }
1228 }
1229
Jamie Madill1fc7e2c2014-01-21 16:47:10 -05001230 return true;
1231}
1232
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001233bool ValidateBlitFramebufferParameters(Context *context,
Jamie Madillc29968b2016-01-20 11:17:23 -05001234 GLint srcX0,
1235 GLint srcY0,
1236 GLint srcX1,
1237 GLint srcY1,
1238 GLint dstX0,
1239 GLint dstY0,
1240 GLint dstX1,
1241 GLint dstY1,
1242 GLbitfield mask,
1243 GLenum filter)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001244{
1245 switch (filter)
1246 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001247 case GL_NEAREST:
1248 break;
1249 case GL_LINEAR:
1250 break;
1251 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001252 context->validationError(GL_INVALID_ENUM, kErrorBlitInvalidFilter);
He Yunchaoced53ae2016-11-29 15:00:51 +08001253 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001254 }
1255
1256 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
1257 {
Jamie Madill610640f2018-11-21 17:28:41 -05001258 context->validationError(GL_INVALID_VALUE, kErrorBlitInvalidMask);
Geoff Langb1196682014-07-23 13:47:29 -04001259 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001260 }
1261
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001262 // ES3.0 spec, section 4.3.2 states that linear filtering is only available for the
1263 // color buffer, leaving only nearest being unfiltered from above
1264 if ((mask & ~GL_COLOR_BUFFER_BIT) != 0 && filter != GL_NEAREST)
1265 {
Jamie Madill610640f2018-11-21 17:28:41 -05001266 context->validationError(GL_INVALID_OPERATION, kErrorBlitOnlyNearestForNonColor);
Geoff Langb1196682014-07-23 13:47:29 -04001267 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001268 }
1269
Jamie Madill7f232932018-09-12 11:03:06 -04001270 const auto &glState = context->getGLState();
1271 Framebuffer *readFramebuffer = glState.getReadFramebuffer();
1272 Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
Jamie Madill48faf802014-11-06 15:27:22 -05001273
1274 if (!readFramebuffer || !drawFramebuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001275 {
Jamie Madill610640f2018-11-21 17:28:41 -05001276 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kErrorBlitFramebufferMissing);
Geoff Langb1196682014-07-23 13:47:29 -04001277 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001278 }
1279
Jamie Madill427064d2018-04-13 16:20:34 -04001280 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001281 {
Jamie Madill48faf802014-11-06 15:27:22 -05001282 return false;
1283 }
1284
Jamie Madill427064d2018-04-13 16:20:34 -04001285 if (!ValidateFramebufferComplete(context, drawFramebuffer))
Jamie Madill48faf802014-11-06 15:27:22 -05001286 {
Jamie Madill48faf802014-11-06 15:27:22 -05001287 return false;
1288 }
1289
Qin Jiajiaaef92162018-02-27 13:51:44 +08001290 if (readFramebuffer->id() == drawFramebuffer->id())
1291 {
Jamie Madill610640f2018-11-21 17:28:41 -05001292 context->validationError(GL_INVALID_OPERATION, kErrorBlitFeedbackLoop);
Qin Jiajiaaef92162018-02-27 13:51:44 +08001293 return false;
1294 }
1295
Jamie Madille98b1b52018-03-08 09:47:23 -05001296 if (!ValidateFramebufferNotMultisampled(context, drawFramebuffer))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001297 {
Geoff Langb1196682014-07-23 13:47:29 -04001298 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001299 }
1300
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001301 // This validation is specified in the WebGL 2.0 spec and not in the GLES 3.0.5 spec, but we
1302 // always run it in order to avoid triggering driver bugs.
1303 if (DifferenceCanOverflow(srcX0, srcX1) || DifferenceCanOverflow(srcY0, srcY1) ||
1304 DifferenceCanOverflow(dstX0, dstX1) || DifferenceCanOverflow(dstY0, dstY1))
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001305 {
Jamie Madill610640f2018-11-21 17:28:41 -05001306 context->validationError(GL_INVALID_VALUE, kErrorBlitDimensionsOutOfRange);
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001307 return false;
Olli Etuaho8d5571a2018-04-23 12:29:31 +03001308 }
1309
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001310 bool sameBounds = srcX0 == dstX0 && srcY0 == dstY0 && srcX1 == dstX1 && srcY1 == dstY1;
1311
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001312 if (mask & GL_COLOR_BUFFER_BIT)
1313 {
Jamie Madill7f232932018-09-12 11:03:06 -04001314 const FramebufferAttachment *readColorBuffer = readFramebuffer->getReadColorbuffer();
1315 const Extensions &extensions = context->getExtensions();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001316
He Yunchao66a41a22016-12-15 16:45:05 +08001317 if (readColorBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001318 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001319 const Format &readFormat = readColorBuffer->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001320
Geoff Langa15472a2015-08-11 11:48:03 -04001321 for (size_t drawbufferIdx = 0;
1322 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001323 {
Geoff Langa15472a2015-08-11 11:48:03 -04001324 const FramebufferAttachment *attachment =
1325 drawFramebuffer->getDrawBuffer(drawbufferIdx);
1326 if (attachment)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001327 {
Jamie Madilla3944d42016-07-22 22:13:26 -04001328 const Format &drawFormat = attachment->getFormat();
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329
Geoff Langb2f3d052013-08-13 12:49:27 -04001330 // The GL ES 3.0.2 spec (pg 193) states that:
1331 // 1) If the read buffer is fixed point format, the draw buffer must be as well
He Yunchaoced53ae2016-11-29 15:00:51 +08001332 // 2) If the read buffer is an unsigned integer format, the draw buffer must be
1333 // as well
1334 // 3) If the read buffer is a signed integer format, the draw buffer must be as
1335 // well
Jamie Madill6163c752015-12-07 16:32:59 -05001336 // Changes with EXT_color_buffer_float:
1337 // Case 1) is changed to fixed point OR floating point
Jamie Madilla3944d42016-07-22 22:13:26 -04001338 GLenum readComponentType = readFormat.info->componentType;
1339 GLenum drawComponentType = drawFormat.info->componentType;
He Yunchaoced53ae2016-11-29 15:00:51 +08001340 bool readFixedPoint = (readComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001341 readComponentType == GL_SIGNED_NORMALIZED);
Lingfeng Yang038dd532018-03-29 17:31:52 -07001342 bool drawFixedPoint = (drawComponentType == GL_UNSIGNED_NORMALIZED ||
Jamie Madill6163c752015-12-07 16:32:59 -05001343 drawComponentType == GL_SIGNED_NORMALIZED);
1344
1345 if (extensions.colorBufferFloat)
1346 {
1347 bool readFixedOrFloat = (readFixedPoint || readComponentType == GL_FLOAT);
1348 bool drawFixedOrFloat = (drawFixedPoint || drawComponentType == GL_FLOAT);
1349
1350 if (readFixedOrFloat != drawFixedOrFloat)
1351 {
Jamie Madill610640f2018-11-21 17:28:41 -05001352 context->validationError(GL_INVALID_OPERATION,
1353 kErrorBlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001354 return false;
1355 }
1356 }
1357 else if (readFixedPoint != drawFixedPoint)
1358 {
Jamie Madill610640f2018-11-21 17:28:41 -05001359 context->validationError(GL_INVALID_OPERATION,
1360 kErrorBlitTypeMismatchFixedPoint);
Jamie Madill6163c752015-12-07 16:32:59 -05001361 return false;
1362 }
1363
1364 if (readComponentType == GL_UNSIGNED_INT &&
1365 drawComponentType != GL_UNSIGNED_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001366 {
Jamie Madill610640f2018-11-21 17:28:41 -05001367 context->validationError(GL_INVALID_OPERATION,
1368 kErrorBlitTypeMismatchUnsignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001369 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001370 }
1371
Jamie Madill6163c752015-12-07 16:32:59 -05001372 if (readComponentType == GL_INT && drawComponentType != GL_INT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001373 {
Jamie Madill610640f2018-11-21 17:28:41 -05001374 context->validationError(GL_INVALID_OPERATION,
1375 kErrorBlitTypeMismatchSignedInteger);
Geoff Langb1196682014-07-23 13:47:29 -04001376 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001377 }
1378
Jamie Madilla3944d42016-07-22 22:13:26 -04001379 if (readColorBuffer->getSamples() > 0 &&
Kenneth Russell69382852017-07-21 16:38:44 -04001380 (!Format::EquivalentForBlit(readFormat, drawFormat) || !sameBounds))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001381 {
Jamie Madill610640f2018-11-21 17:28:41 -05001382 context->validationError(GL_INVALID_OPERATION,
1383 kErrorBlitMultisampledFormatOrBoundsMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001384 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001385 }
Geoff Lange4915782017-04-12 15:19:07 -04001386
1387 if (context->getExtensions().webglCompatibility &&
1388 *readColorBuffer == *attachment)
1389 {
Jamie Madill610640f2018-11-21 17:28:41 -05001390 context->validationError(GL_INVALID_OPERATION, kErrorBlitSameImageColor);
Geoff Lange4915782017-04-12 15:19:07 -04001391 return false;
1392 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001393 }
1394 }
1395
Jamie Madilla3944d42016-07-22 22:13:26 -04001396 if ((readFormat.info->componentType == GL_INT ||
1397 readFormat.info->componentType == GL_UNSIGNED_INT) &&
1398 filter == GL_LINEAR)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001399 {
Jamie Madill610640f2018-11-21 17:28:41 -05001400 context->validationError(GL_INVALID_OPERATION, kErrorBlitIntegerWithLinearFilter);
Geoff Langb1196682014-07-23 13:47:29 -04001401 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001402 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001403 }
He Yunchao66a41a22016-12-15 16:45:05 +08001404 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1405 // In OpenGL ES it is undefined what happens when an operation tries to blit from a missing
1406 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
1407 // situation is an application error that would lead to a crash in ANGLE.
1408 else if (drawFramebuffer->hasEnabledDrawBuffer())
1409 {
Jamie Madill610640f2018-11-21 17:28:41 -05001410 context->validationError(GL_INVALID_OPERATION, kErrorBlitMissingColor);
He Yunchao66a41a22016-12-15 16:45:05 +08001411 return false;
1412 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001413 }
1414
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001416 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
1417 for (size_t i = 0; i < 2; i++)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001418 {
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001419 if (mask & masks[i])
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001420 {
Jamie Madill43da7c42018-08-01 11:34:49 -04001421 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001422 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madill43da7c42018-08-01 11:34:49 -04001423 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08001424 drawFramebuffer->getAttachment(context, attachments[i]);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001425
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001426 if (readBuffer && drawBuffer)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001427 {
Kenneth Russell69382852017-07-21 16:38:44 -04001428 if (!Format::EquivalentForBlit(readBuffer->getFormat(), drawBuffer->getFormat()))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001429 {
Jamie Madill610640f2018-11-21 17:28:41 -05001430 context->validationError(GL_INVALID_OPERATION,
1431 kErrorBlitDepthOrStencilFormatMismatch);
Geoff Langb1196682014-07-23 13:47:29 -04001432 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001433 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001434
Dongseong Hwang44b422c2014-12-09 15:42:01 +02001435 if (readBuffer->getSamples() > 0 && !sameBounds)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001436 {
Jamie Madill610640f2018-11-21 17:28:41 -05001437 context->validationError(GL_INVALID_OPERATION,
1438 kErrorBlitMultisampledBoundsMismatch);
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 Madill610640f2018-11-21 17:28:41 -05001444 context->validationError(GL_INVALID_OPERATION,
1445 kErrorBlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001446 return false;
1447 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001448 }
He Yunchao66a41a22016-12-15 16:45:05 +08001449 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1450 else if (drawBuffer)
1451 {
Jamie Madill610640f2018-11-21 17:28:41 -05001452 context->validationError(GL_INVALID_OPERATION, kErrorBlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001453 return false;
1454 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001455 }
1456 }
1457
Martin Radeva3ed4572017-07-27 18:29:37 +03001458 // ANGLE_multiview, Revision 1:
1459 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001460 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1461 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1462 // views in the current read framebuffer is more than one.
1463 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001464 {
Jamie Madill610640f2018-11-21 17:28:41 -05001465 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kErrorBlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001466 return false;
1467 }
1468 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1469 {
Jamie Madill610640f2018-11-21 17:28:41 -05001470 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION, kErrorBlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001471 return false;
1472 }
1473
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001474 return true;
1475}
1476
Jamie Madill4928b7c2017-06-20 12:57:39 -04001477bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001478 GLint x,
1479 GLint y,
1480 GLsizei width,
1481 GLsizei height,
1482 GLenum format,
1483 GLenum type,
1484 GLsizei bufSize,
1485 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001486 GLsizei *columns,
1487 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001488 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001489{
1490 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001491 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001492 return false;
1493 }
1494
Brandon Jonesd1049182018-03-28 10:02:20 -07001495 GLsizei writeLength = 0;
1496 GLsizei writeColumns = 0;
1497 GLsizei writeRows = 0;
1498
1499 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1500 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001501 {
Geoff Langb1196682014-07-23 13:47:29 -04001502 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001503 }
1504
Brandon Jonesd1049182018-03-28 10:02:20 -07001505 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001506 {
Geoff Langb1196682014-07-23 13:47:29 -04001507 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001508 }
1509
Brandon Jonesd1049182018-03-28 10:02:20 -07001510 SetRobustLengthParam(length, writeLength);
1511 SetRobustLengthParam(columns, writeColumns);
1512 SetRobustLengthParam(rows, writeRows);
1513
Jamie Madillc29968b2016-01-20 11:17:23 -05001514 return true;
1515}
1516
1517bool ValidateReadnPixelsEXT(Context *context,
1518 GLint x,
1519 GLint y,
1520 GLsizei width,
1521 GLsizei height,
1522 GLenum format,
1523 GLenum type,
1524 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001525 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001526{
1527 if (bufSize < 0)
1528 {
Jamie Madill610640f2018-11-21 17:28:41 -05001529 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001530 return false;
1531 }
1532
Geoff Lang62fce5b2016-09-30 10:46:35 -04001533 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001534 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001535}
Jamie Madill26e91952014-03-05 15:01:27 -05001536
Jamie Madill4928b7c2017-06-20 12:57:39 -04001537bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001538 GLint x,
1539 GLint y,
1540 GLsizei width,
1541 GLsizei height,
1542 GLenum format,
1543 GLenum type,
1544 GLsizei bufSize,
1545 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001546 GLsizei *columns,
1547 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001548 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001549{
Brandon Jonesd1049182018-03-28 10:02:20 -07001550 GLsizei writeLength = 0;
1551 GLsizei writeColumns = 0;
1552 GLsizei writeRows = 0;
1553
Geoff Lang62fce5b2016-09-30 10:46:35 -04001554 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001555 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001556 return false;
1557 }
1558
Brandon Jonesd1049182018-03-28 10:02:20 -07001559 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1560 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001561 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001562 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001563 }
1564
Brandon Jonesd1049182018-03-28 10:02:20 -07001565 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001566 {
1567 return false;
1568 }
1569
Brandon Jonesd1049182018-03-28 10:02:20 -07001570 SetRobustLengthParam(length, writeLength);
1571 SetRobustLengthParam(columns, writeColumns);
1572 SetRobustLengthParam(rows, writeRows);
1573
Geoff Lang62fce5b2016-09-30 10:46:35 -04001574 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001575}
1576
Jamie Madill43da7c42018-08-01 11:34:49 -04001577bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001578{
1579 if (!context->getExtensions().occlusionQueryBoolean &&
1580 !context->getExtensions().disjointTimerQuery)
1581 {
Jamie Madill610640f2018-11-21 17:28:41 -05001582 context->validationError(GL_INVALID_OPERATION, kErrorQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001583 return false;
1584 }
1585
Olli Etuaho41997e72016-03-10 13:38:39 +02001586 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001587}
1588
Jamie Madill43da7c42018-08-01 11:34:49 -04001589bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001590{
1591 if (!context->getExtensions().occlusionQueryBoolean &&
1592 !context->getExtensions().disjointTimerQuery)
1593 {
Jamie Madill610640f2018-11-21 17:28:41 -05001594 context->validationError(GL_INVALID_OPERATION, kErrorQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001595 return false;
1596 }
1597
Olli Etuaho41997e72016-03-10 13:38:39 +02001598 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001599}
1600
Jamie Madill43da7c42018-08-01 11:34:49 -04001601bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001602{
1603 if (!context->getExtensions().occlusionQueryBoolean &&
1604 !context->getExtensions().disjointTimerQuery)
1605 {
Jamie Madill610640f2018-11-21 17:28:41 -05001606 context->validationError(GL_INVALID_OPERATION, kErrorQueryExtensionNotEnabled);
Jamie Madillf0e04492017-08-26 15:28:42 -04001607 return false;
1608 }
1609
1610 return true;
1611}
1612
Jamie Madill43da7c42018-08-01 11:34:49 -04001613bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001614{
1615 if (!ValidQueryType(context, target))
1616 {
Jamie Madill610640f2018-11-21 17:28:41 -05001617 context->validationError(GL_INVALID_ENUM, kErrorInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001618 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001619 }
1620
1621 if (id == 0)
1622 {
Jamie Madill610640f2018-11-21 17:28:41 -05001623 context->validationError(GL_INVALID_OPERATION, "Query id is 0");
Geoff Langb1196682014-07-23 13:47:29 -04001624 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001625 }
1626
1627 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1628 // of zero, if the active query object name for <target> is non-zero (for the
1629 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1630 // the active query for either target is non-zero), if <id> is the name of an
1631 // existing query object whose type does not match <target>, or if <id> is the
1632 // active query object name for any query type, the error INVALID_OPERATION is
1633 // generated.
1634
1635 // Ensure no other queries are active
1636 // NOTE: If other queries than occlusion are supported, we will need to check
1637 // separately that:
1638 // a) The query ID passed is not the current active query for any target/type
1639 // b) There are no active queries for the requested target (and in the case
1640 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1641 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001642
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001643 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001644 {
Jamie Madill610640f2018-11-21 17:28:41 -05001645 context->validationError(GL_INVALID_OPERATION, "Other query is active");
Geoff Langb1196682014-07-23 13:47:29 -04001646 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001647 }
1648
1649 Query *queryObject = context->getQuery(id, true, target);
1650
1651 // check that name was obtained with glGenQueries
1652 if (!queryObject)
1653 {
Jamie Madill610640f2018-11-21 17:28:41 -05001654 context->validationError(GL_INVALID_OPERATION, kErrorInvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001655 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001656 }
1657
1658 // check for type mismatch
1659 if (queryObject->getType() != target)
1660 {
Jamie Madill610640f2018-11-21 17:28:41 -05001661 context->validationError(GL_INVALID_OPERATION, "Query type does not match target");
Geoff Langb1196682014-07-23 13:47:29 -04001662 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001663 }
1664
1665 return true;
1666}
1667
Jamie Madill43da7c42018-08-01 11:34:49 -04001668bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001669{
1670 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001671 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001672 {
Jamie Madill610640f2018-11-21 17:28:41 -05001673 context->validationError(GL_INVALID_OPERATION, kErrorQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001674 return false;
1675 }
1676
1677 return ValidateBeginQueryBase(context, target, id);
1678}
1679
Jamie Madill43da7c42018-08-01 11:34:49 -04001680bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001681{
1682 if (!ValidQueryType(context, target))
1683 {
Jamie Madill610640f2018-11-21 17:28:41 -05001684 context->validationError(GL_INVALID_ENUM, kErrorInvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001685 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001686 }
1687
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001688 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001689
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001690 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001691 {
Jamie Madill610640f2018-11-21 17:28:41 -05001692 context->validationError(GL_INVALID_OPERATION, "Query target not active");
Geoff Langb1196682014-07-23 13:47:29 -04001693 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001694 }
1695
Jamie Madill45c785d2014-05-13 14:09:34 -04001696 return true;
1697}
1698
Jamie Madill43da7c42018-08-01 11:34:49 -04001699bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001700{
1701 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001702 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001703 {
Jamie Madill610640f2018-11-21 17:28:41 -05001704 context->validationError(GL_INVALID_OPERATION, kErrorQueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001705 return false;
1706 }
1707
1708 return ValidateEndQueryBase(context, target);
1709}
1710
Corentin Wallezad3ae902018-03-09 13:40:42 -05001711bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001712{
1713 if (!context->getExtensions().disjointTimerQuery)
1714 {
Jamie Madill610640f2018-11-21 17:28:41 -05001715 context->validationError(GL_INVALID_OPERATION, "Disjoint timer query not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001716 return false;
1717 }
1718
Corentin Wallezad3ae902018-03-09 13:40:42 -05001719 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001720 {
Jamie Madill610640f2018-11-21 17:28:41 -05001721 context->validationError(GL_INVALID_ENUM, kErrorInvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001722 return false;
1723 }
1724
1725 Query *queryObject = context->getQuery(id, true, target);
1726 if (queryObject == nullptr)
1727 {
Jamie Madill610640f2018-11-21 17:28:41 -05001728 context->validationError(GL_INVALID_OPERATION, kErrorInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001729 return false;
1730 }
1731
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001732 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001733 {
Jamie Madill610640f2018-11-21 17:28:41 -05001734 context->validationError(GL_INVALID_OPERATION, kErrorQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001735 return false;
1736 }
1737
1738 return true;
1739}
1740
Corentin Wallezad3ae902018-03-09 13:40:42 -05001741bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001742{
Geoff Lang2186c382016-10-14 10:54:54 -04001743 if (numParams)
1744 {
1745 *numParams = 0;
1746 }
1747
Corentin Wallezad3ae902018-03-09 13:40:42 -05001748 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001749 {
Jamie Madill610640f2018-11-21 17:28:41 -05001750 context->validationError(GL_INVALID_ENUM, kErrorInvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001751 return false;
1752 }
1753
1754 switch (pname)
1755 {
1756 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001757 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001758 {
Jamie Madill610640f2018-11-21 17:28:41 -05001759 context->validationError(GL_INVALID_ENUM, "Cannot use current query for timestamp");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001760 return false;
1761 }
1762 break;
1763 case GL_QUERY_COUNTER_BITS_EXT:
1764 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001765 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001766 {
Jamie Madill610640f2018-11-21 17:28:41 -05001767 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001768 return false;
1769 }
1770 break;
1771 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001772 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001773 return false;
1774 }
1775
Geoff Lang2186c382016-10-14 10:54:54 -04001776 if (numParams)
1777 {
1778 // All queries return only one value
1779 *numParams = 1;
1780 }
1781
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001782 return true;
1783}
1784
Corentin Wallezad3ae902018-03-09 13:40:42 -05001785bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001786{
1787 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001788 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001789 {
Jamie Madill610640f2018-11-21 17:28:41 -05001790 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001791 return false;
1792 }
1793
Geoff Lang2186c382016-10-14 10:54:54 -04001794 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001795}
1796
Geoff Lang2186c382016-10-14 10:54:54 -04001797bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001798 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001799 GLenum pname,
1800 GLsizei bufSize,
1801 GLsizei *length,
1802 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001803{
Geoff Lang2186c382016-10-14 10:54:54 -04001804 if (!ValidateRobustEntryPoint(context, bufSize))
1805 {
1806 return false;
1807 }
1808
Brandon Jonesd1049182018-03-28 10:02:20 -07001809 GLsizei numParams = 0;
1810
1811 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001812 {
1813 return false;
1814 }
1815
Brandon Jonesd1049182018-03-28 10:02:20 -07001816 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001817 {
1818 return false;
1819 }
1820
Brandon Jonesd1049182018-03-28 10:02:20 -07001821 SetRobustLengthParam(length, numParams);
1822
Geoff Lang2186c382016-10-14 10:54:54 -04001823 return true;
1824}
1825
1826bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1827{
1828 if (numParams)
1829 {
1830 *numParams = 0;
1831 }
1832
Corentin Wallezad3ae902018-03-09 13:40:42 -05001833 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001834
1835 if (!queryObject)
1836 {
Jamie Madill610640f2018-11-21 17:28:41 -05001837 context->validationError(GL_INVALID_OPERATION, kErrorInvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001838 return false;
1839 }
1840
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001841 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001842 {
Jamie Madill610640f2018-11-21 17:28:41 -05001843 context->validationError(GL_INVALID_OPERATION, kErrorQueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001844 return false;
1845 }
1846
1847 switch (pname)
1848 {
1849 case GL_QUERY_RESULT_EXT:
1850 case GL_QUERY_RESULT_AVAILABLE_EXT:
1851 break;
1852
1853 default:
Jamie Madill610640f2018-11-21 17:28:41 -05001854 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001855 return false;
1856 }
1857
Geoff Lang2186c382016-10-14 10:54:54 -04001858 if (numParams)
1859 {
1860 *numParams = 1;
1861 }
1862
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001863 return true;
1864}
1865
1866bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1867{
1868 if (!context->getExtensions().disjointTimerQuery)
1869 {
Jamie Madill610640f2018-11-21 17:28:41 -05001870 context->validationError(GL_INVALID_OPERATION, "Timer query extension not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001871 return false;
1872 }
Geoff Lang2186c382016-10-14 10:54:54 -04001873 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1874}
1875
1876bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1877 GLuint id,
1878 GLenum pname,
1879 GLsizei bufSize,
1880 GLsizei *length,
1881 GLint *params)
1882{
1883 if (!context->getExtensions().disjointTimerQuery)
1884 {
Jamie Madill610640f2018-11-21 17:28:41 -05001885 context->validationError(GL_INVALID_OPERATION, "Timer query extension not enabled");
Geoff Lang2186c382016-10-14 10:54:54 -04001886 return false;
1887 }
1888
1889 if (!ValidateRobustEntryPoint(context, bufSize))
1890 {
1891 return false;
1892 }
1893
Brandon Jonesd1049182018-03-28 10:02:20 -07001894 GLsizei numParams = 0;
1895
1896 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001897 {
1898 return false;
1899 }
1900
Brandon Jonesd1049182018-03-28 10:02:20 -07001901 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001902 {
1903 return false;
1904 }
1905
Brandon Jonesd1049182018-03-28 10:02:20 -07001906 SetRobustLengthParam(length, numParams);
1907
Geoff Lang2186c382016-10-14 10:54:54 -04001908 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001909}
1910
1911bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1912{
1913 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001914 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001915 {
Jamie Madill610640f2018-11-21 17:28:41 -05001916 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001917 return false;
1918 }
Geoff Lang2186c382016-10-14 10:54:54 -04001919 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1920}
1921
1922bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1923 GLuint id,
1924 GLenum pname,
1925 GLsizei bufSize,
1926 GLsizei *length,
1927 GLuint *params)
1928{
1929 if (!context->getExtensions().disjointTimerQuery &&
1930 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1931 {
Jamie Madill610640f2018-11-21 17:28:41 -05001932 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001933 return false;
1934 }
1935
1936 if (!ValidateRobustEntryPoint(context, bufSize))
1937 {
1938 return false;
1939 }
1940
Brandon Jonesd1049182018-03-28 10:02:20 -07001941 GLsizei numParams = 0;
1942
1943 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001944 {
1945 return false;
1946 }
1947
Brandon Jonesd1049182018-03-28 10:02:20 -07001948 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001949 {
1950 return false;
1951 }
1952
Brandon Jonesd1049182018-03-28 10:02:20 -07001953 SetRobustLengthParam(length, numParams);
1954
Geoff Lang2186c382016-10-14 10:54:54 -04001955 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001956}
1957
1958bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1959{
1960 if (!context->getExtensions().disjointTimerQuery)
1961 {
Jamie Madill610640f2018-11-21 17:28:41 -05001962 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001963 return false;
1964 }
Geoff Lang2186c382016-10-14 10:54:54 -04001965 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1966}
1967
1968bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1969 GLuint id,
1970 GLenum pname,
1971 GLsizei bufSize,
1972 GLsizei *length,
1973 GLint64 *params)
1974{
1975 if (!context->getExtensions().disjointTimerQuery)
1976 {
Jamie Madill610640f2018-11-21 17:28:41 -05001977 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001978 return false;
1979 }
1980
1981 if (!ValidateRobustEntryPoint(context, bufSize))
1982 {
1983 return false;
1984 }
1985
Brandon Jonesd1049182018-03-28 10:02:20 -07001986 GLsizei numParams = 0;
1987
1988 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001989 {
1990 return false;
1991 }
1992
Brandon Jonesd1049182018-03-28 10:02:20 -07001993 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001994 {
1995 return false;
1996 }
1997
Brandon Jonesd1049182018-03-28 10:02:20 -07001998 SetRobustLengthParam(length, numParams);
1999
Geoff Lang2186c382016-10-14 10:54:54 -04002000 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002001}
2002
2003bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
2004{
2005 if (!context->getExtensions().disjointTimerQuery)
2006 {
Jamie Madill610640f2018-11-21 17:28:41 -05002007 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002008 return false;
2009 }
Geoff Lang2186c382016-10-14 10:54:54 -04002010 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
2011}
2012
2013bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
2014 GLuint id,
2015 GLenum pname,
2016 GLsizei bufSize,
2017 GLsizei *length,
2018 GLuint64 *params)
2019{
2020 if (!context->getExtensions().disjointTimerQuery)
2021 {
Jamie Madill610640f2018-11-21 17:28:41 -05002022 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002023 return false;
2024 }
2025
2026 if (!ValidateRobustEntryPoint(context, bufSize))
2027 {
2028 return false;
2029 }
2030
Brandon Jonesd1049182018-03-28 10:02:20 -07002031 GLsizei numParams = 0;
2032
2033 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002034 {
2035 return false;
2036 }
2037
Brandon Jonesd1049182018-03-28 10:02:20 -07002038 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002039 {
2040 return false;
2041 }
2042
Brandon Jonesd1049182018-03-28 10:02:20 -07002043 SetRobustLengthParam(length, numParams);
2044
Geoff Lang2186c382016-10-14 10:54:54 -04002045 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002046}
2047
Jamie Madill5b772312018-03-08 20:28:32 -05002048bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002049 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002050 GLint location,
2051 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002052 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002053{
Jiajia Qin5451d532017-11-16 17:16:34 +08002054 // TODO(Jiajia): Add image uniform check in future.
2055 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002056 {
Jamie Madill610640f2018-11-21 17:28:41 -05002057 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002058 return false;
2059 }
2060
Jiajia Qin5451d532017-11-16 17:16:34 +08002061 if (!program)
2062 {
Jamie Madill610640f2018-11-21 17:28:41 -05002063 context->validationError(GL_INVALID_OPERATION, kErrorInvalidProgramName);
Jiajia Qin5451d532017-11-16 17:16:34 +08002064 return false;
2065 }
2066
2067 if (!program->isLinked())
2068 {
Jamie Madill610640f2018-11-21 17:28:41 -05002069 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jiajia Qin5451d532017-11-16 17:16:34 +08002070 return false;
2071 }
2072
2073 if (location == -1)
2074 {
2075 // Silently ignore the uniform command
2076 return false;
2077 }
2078
2079 const auto &uniformLocations = program->getUniformLocations();
2080 size_t castedLocation = static_cast<size_t>(location);
2081 if (castedLocation >= uniformLocations.size())
2082 {
Jamie Madill610640f2018-11-21 17:28:41 -05002083 context->validationError(GL_INVALID_OPERATION, kErrorInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002084 return false;
2085 }
2086
2087 const auto &uniformLocation = uniformLocations[castedLocation];
2088 if (uniformLocation.ignored)
2089 {
2090 // Silently ignore the uniform command
2091 return false;
2092 }
2093
2094 if (!uniformLocation.used())
2095 {
Jamie Madill610640f2018-11-21 17:28:41 -05002096 context->validationError(GL_INVALID_OPERATION, kErrorInvalidUniformLocation);
Jiajia Qin5451d532017-11-16 17:16:34 +08002097 return false;
2098 }
2099
2100 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2101
2102 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002103 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002104 {
Jamie Madill610640f2018-11-21 17:28:41 -05002105 context->validationError(GL_INVALID_OPERATION, kErrorInvalidUniformCount);
Jiajia Qin5451d532017-11-16 17:16:34 +08002106 return false;
2107 }
2108
2109 *uniformOut = &uniform;
2110 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002111}
2112
Jamie Madill5b772312018-03-08 20:28:32 -05002113bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002114 GLenum uniformType,
2115 GLsizei count,
2116 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002117{
Jiajia Qin5451d532017-11-16 17:16:34 +08002118 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2119 // It is compatible with INT or BOOL.
2120 // Do these cheap tests first, for a little extra speed.
2121 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002122 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002123 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002124 }
2125
Jiajia Qin5451d532017-11-16 17:16:34 +08002126 if (IsSamplerType(uniformType))
2127 {
2128 // Check that the values are in range.
2129 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2130 for (GLsizei i = 0; i < count; ++i)
2131 {
2132 if (value[i] < 0 || value[i] >= max)
2133 {
Jamie Madill610640f2018-11-21 17:28:41 -05002134 context->validationError(GL_INVALID_VALUE, "sampler uniform value out of range");
Jiajia Qin5451d532017-11-16 17:16:34 +08002135 return false;
2136 }
2137 }
2138 return true;
2139 }
2140
Jamie Madill610640f2018-11-21 17:28:41 -05002141 context->validationError(GL_INVALID_OPERATION, "wrong type of value for uniform");
Jiajia Qin5451d532017-11-16 17:16:34 +08002142 return false;
2143}
2144
Jamie Madill5b772312018-03-08 20:28:32 -05002145bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002146{
2147 // Check that the value type is compatible with uniform type.
2148 if (valueType == uniformType)
2149 {
2150 return true;
2151 }
2152
Jamie Madill610640f2018-11-21 17:28:41 -05002153 context->validationError(GL_INVALID_OPERATION, "wrong type of value for uniform");
Jiajia Qin5451d532017-11-16 17:16:34 +08002154 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002155}
2156
Jamie Madill5b772312018-03-08 20:28:32 -05002157bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002158{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002159 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002160 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002161 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2162 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002163}
2164
Jamie Madill5b772312018-03-08 20:28:32 -05002165bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002166{
2167 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002168 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002169 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2170 ValidateUniform1ivValue(context, uniform->type, count, value);
2171}
2172
Jamie Madill5b772312018-03-08 20:28:32 -05002173bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002174 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002175 GLint location,
2176 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002177 GLboolean transpose)
2178{
Geoff Lang92019432017-11-20 13:09:34 -05002179 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002180 {
Jamie Madill610640f2018-11-21 17:28:41 -05002181 context->validationError(GL_INVALID_VALUE, kErrorES3Required);
Geoff Langb1196682014-07-23 13:47:29 -04002182 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002183 }
2184
Jamie Madill62d31cb2015-09-11 13:25:51 -04002185 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002186 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002187 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2188 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002189}
2190
Jamie Madill5b772312018-03-08 20:28:32 -05002191bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002192{
2193 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2194 {
Jamie Madill610640f2018-11-21 17:28:41 -05002195 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Geoff Langb1196682014-07-23 13:47:29 -04002196 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002197 }
2198
Jamie Madill0af26e12015-03-05 19:54:33 -05002199 const Caps &caps = context->getCaps();
2200
Jamie Madill893ab082014-05-16 16:56:10 -04002201 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2202 {
2203 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2204
Jamie Madill0af26e12015-03-05 19:54:33 -05002205 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002206 {
Jamie Madill610640f2018-11-21 17:28:41 -05002207 context->validationError(GL_INVALID_OPERATION, kErrorIndexExceedsMaxDrawBuffer);
Geoff Langb1196682014-07-23 13:47:29 -04002208 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002209 }
2210 }
2211
2212 switch (pname)
2213 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002214 case GL_TEXTURE_BINDING_2D:
2215 case GL_TEXTURE_BINDING_CUBE_MAP:
2216 case GL_TEXTURE_BINDING_3D:
2217 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002218 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002219 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002220 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002221 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002222 {
Jamie Madill610640f2018-11-21 17:28:41 -05002223 context->validationError(GL_INVALID_ENUM, kErrorMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03002224 return false;
2225 }
2226 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002227 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2228 if (!context->getExtensions().textureRectangle)
2229 {
Jamie Madill610640f2018-11-21 17:28:41 -05002230 context->validationError(GL_INVALID_ENUM,
2231 "ANGLE_texture_rectangle extension not present");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002232 return false;
2233 }
2234 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002235 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2236 if (!context->getExtensions().eglStreamConsumerExternal &&
2237 !context->getExtensions().eglImageExternal)
2238 {
Jamie Madill610640f2018-11-21 17:28:41 -05002239 context->validationError(GL_INVALID_ENUM,
2240 "Neither NV_EGL_stream_consumer_external "
2241 "nor GL_OES_EGL_image_external "
2242 "extensions enabled");
He Yunchaoced53ae2016-11-29 15:00:51 +08002243 return false;
2244 }
2245 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002246
He Yunchaoced53ae2016-11-29 15:00:51 +08002247 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2248 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002249 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002250 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2251 ASSERT(readFramebuffer);
2252
Jamie Madill610640f2018-11-21 17:28:41 -05002253 if (!ValidateFramebufferComplete<GL_INVALID_OPERATION>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002254 {
Geoff Langb1196682014-07-23 13:47:29 -04002255 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002256 }
2257
Jamie Madille98b1b52018-03-08 09:47:23 -05002258 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002259 {
Jamie Madill610640f2018-11-21 17:28:41 -05002260 context->validationError(GL_INVALID_OPERATION, kErrorReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002261 return false;
2262 }
2263
Jamie Madille98b1b52018-03-08 09:47:23 -05002264 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002265 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002266 {
Jamie Madill610640f2018-11-21 17:28:41 -05002267 context->validationError(GL_INVALID_OPERATION, kErrorReadBufferNotAttached);
Geoff Langb1196682014-07-23 13:47:29 -04002268 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002269 }
2270 }
2271 break;
2272
He Yunchaoced53ae2016-11-29 15:00:51 +08002273 default:
2274 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002275 }
2276
2277 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002278 if (*numParams == 0)
2279 {
2280 return false;
2281 }
2282
2283 return true;
2284}
2285
Brandon Jonesd1049182018-03-28 10:02:20 -07002286bool ValidateGetBooleanvRobustANGLE(Context *context,
2287 GLenum pname,
2288 GLsizei bufSize,
2289 GLsizei *length,
2290 GLboolean *params)
2291{
2292 GLenum nativeType;
2293 unsigned int numParams = 0;
2294
2295 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2296 {
2297 return false;
2298 }
2299
2300 SetRobustLengthParam(length, numParams);
2301
2302 return true;
2303}
2304
2305bool ValidateGetFloatvRobustANGLE(Context *context,
2306 GLenum pname,
2307 GLsizei bufSize,
2308 GLsizei *length,
2309 GLfloat *params)
2310{
2311 GLenum nativeType;
2312 unsigned int numParams = 0;
2313
2314 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2315 {
2316 return false;
2317 }
2318
2319 SetRobustLengthParam(length, numParams);
2320
2321 return true;
2322}
2323
2324bool ValidateGetIntegervRobustANGLE(Context *context,
2325 GLenum pname,
2326 GLsizei bufSize,
2327 GLsizei *length,
2328 GLint *data)
2329{
2330 GLenum nativeType;
2331 unsigned int numParams = 0;
2332
2333 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2334 {
2335 return false;
2336 }
2337
2338 SetRobustLengthParam(length, numParams);
2339
2340 return true;
2341}
2342
2343bool ValidateGetInteger64vRobustANGLE(Context *context,
2344 GLenum pname,
2345 GLsizei bufSize,
2346 GLsizei *length,
2347 GLint64 *data)
2348{
2349 GLenum nativeType;
2350 unsigned int numParams = 0;
2351
2352 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2353 {
2354 return false;
2355 }
2356
2357 if (nativeType == GL_INT_64_ANGLEX)
2358 {
2359 CastStateValues(context, nativeType, pname, numParams, data);
2360 return false;
2361 }
2362
2363 SetRobustLengthParam(length, numParams);
2364 return true;
2365}
2366
Jamie Madill5b772312018-03-08 20:28:32 -05002367bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002368 GLenum pname,
2369 GLsizei bufSize,
2370 GLenum *nativeType,
2371 unsigned int *numParams)
2372{
2373 if (!ValidateRobustEntryPoint(context, bufSize))
2374 {
2375 return false;
2376 }
2377
2378 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2379 {
2380 return false;
2381 }
2382
2383 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002384 {
2385 return false;
2386 }
2387
2388 return true;
2389}
2390
Jamie Madill5b772312018-03-08 20:28:32 -05002391bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002392 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002393 GLint level,
2394 GLenum internalformat,
2395 bool isSubImage,
2396 GLint xoffset,
2397 GLint yoffset,
2398 GLint zoffset,
2399 GLint x,
2400 GLint y,
2401 GLsizei width,
2402 GLsizei height,
2403 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002404 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002405{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002406 TextureType texType = TextureTargetToType(target);
2407
Brandon Jones6cad5662017-06-14 13:25:13 -07002408 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002409 {
Jamie Madill610640f2018-11-21 17:28:41 -05002410 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07002411 return false;
2412 }
2413
2414 if (width < 0 || height < 0)
2415 {
Jamie Madill610640f2018-11-21 17:28:41 -05002416 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002417 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002418 }
2419
He Yunchaoced53ae2016-11-29 15:00:51 +08002420 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2421 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002422 {
Jamie Madill610640f2018-11-21 17:28:41 -05002423 context->validationError(GL_INVALID_VALUE, kErrorOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002424 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002425 }
2426
2427 if (border != 0)
2428 {
Jamie Madill610640f2018-11-21 17:28:41 -05002429 context->validationError(GL_INVALID_VALUE, kErrorInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002430 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002431 }
2432
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002433 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002434 {
Jamie Madill610640f2018-11-21 17:28:41 -05002435 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002436 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002437 }
2438
Jamie Madill43da7c42018-08-01 11:34:49 -04002439 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002440 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002441 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002442 {
Geoff Langb1196682014-07-23 13:47:29 -04002443 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002444 }
2445
Jamie Madille98b1b52018-03-08 09:47:23 -05002446 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002447 {
Geoff Langb1196682014-07-23 13:47:29 -04002448 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002449 }
2450
Martin Radev138064f2016-07-15 12:03:41 +03002451 if (readFramebuffer->getReadBufferState() == GL_NONE)
2452 {
Jamie Madill610640f2018-11-21 17:28:41 -05002453 context->validationError(GL_INVALID_OPERATION, kErrorReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002454 return false;
2455 }
2456
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002457 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2458 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002459 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002460 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002461 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2462 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002463 {
Jamie Madill610640f2018-11-21 17:28:41 -05002464 context->validationError(GL_INVALID_OPERATION, kErrorMissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002465 return false;
2466 }
2467
Martin Radev04e2c3b2017-07-27 16:54:35 +03002468 // ANGLE_multiview spec, Revision 1:
2469 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2470 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002471 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2472 // framebuffer is more than one.
2473 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002474 {
Jamie Madill610640f2018-11-21 17:28:41 -05002475 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
2476 "The active read framebuffer object has multiview attachments.");
Martin Radev04e2c3b2017-07-27 16:54:35 +03002477 return false;
2478 }
2479
Jamie Madill43da7c42018-08-01 11:34:49 -04002480 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002481
Geoff Langaae65a42014-05-26 12:43:44 -04002482 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002483 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002484 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002485 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002486 maxDimension = caps.max2DTextureSize;
2487 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002488
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002489 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002490 maxDimension = caps.maxCubeMapTextureSize;
2491 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002492
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002493 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002494 maxDimension = caps.maxRectangleTextureSize;
2495 break;
2496
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002497 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002498 maxDimension = caps.max2DTextureSize;
2499 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002500
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002501 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002502 maxDimension = caps.max3DTextureSize;
2503 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002504
He Yunchaoced53ae2016-11-29 15:00:51 +08002505 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002506 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08002507 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002508 }
2509
Jamie Madill43da7c42018-08-01 11:34:49 -04002510 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002511 if (!texture)
2512 {
Jamie Madill610640f2018-11-21 17:28:41 -05002513 context->validationError(GL_INVALID_OPERATION, kErrorTextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002514 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002515 }
2516
Geoff Lang69cce582015-09-17 13:20:36 -04002517 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002518 {
Jamie Madill610640f2018-11-21 17:28:41 -05002519 context->validationError(GL_INVALID_OPERATION, kErrorTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04002520 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002521 }
2522
Jamie Madill43da7c42018-08-01 11:34:49 -04002523 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002524 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002525 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002526
Geoff Lang966c9402017-04-18 12:38:27 -04002527 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002528 {
Jamie Madill610640f2018-11-21 17:28:41 -05002529 context->validationError(GL_INVALID_OPERATION, kErrorInvalidFormat);
Geoff Langa9be0dc2014-12-17 12:34:40 -05002530 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002531 }
2532
2533 if (isSubImage)
2534 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002535 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2536 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2537 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002538 {
Jamie Madill610640f2018-11-21 17:28:41 -05002539 context->validationError(GL_INVALID_VALUE, kErrorOffsetOverflow);
Geoff Langb1196682014-07-23 13:47:29 -04002540 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002541 }
2542 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002543 else
2544 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002545 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002546 {
Jamie Madill610640f2018-11-21 17:28:41 -05002547 context->validationError(GL_INVALID_VALUE, kErrorCubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002548 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002549 }
2550
Geoff Langeb66a6e2016-10-31 13:06:12 -04002551 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002552 {
Jamie Madill610640f2018-11-21 17:28:41 -05002553 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002554 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002555 }
2556
2557 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002558 if (static_cast<int>(width) > maxLevelDimension ||
2559 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002560 {
Jamie Madill610640f2018-11-21 17:28:41 -05002561 context->validationError(GL_INVALID_VALUE, kErrorResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002562 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002563 }
2564 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002565
Jamie Madill0c8abca2016-07-22 20:21:26 -04002566 if (textureFormatOut)
2567 {
2568 *textureFormatOut = texture->getFormat(target, level);
2569 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002570
2571 // Detect texture copying feedback loops for WebGL.
2572 if (context->getExtensions().webglCompatibility)
2573 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002574 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002575 {
Jamie Madill610640f2018-11-21 17:28:41 -05002576 context->validationError(GL_INVALID_OPERATION, kErrorFeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002577 return false;
2578 }
2579 }
2580
Jamie Madill560a8d82014-05-21 13:06:20 -04002581 return true;
2582}
2583
Jamie Madillb42162f2018-08-20 12:58:37 -04002584// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2585// completeness check.
2586const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002587{
2588 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002589 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002590
2591 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2592 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2593 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002594 VertexArray *vertexArray = state.getVertexArray();
2595 ASSERT(vertexArray);
2596
2597 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002598 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002599 return kErrorBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002600 }
2601
2602 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2603 // Section 6.10 of the WebGL 1.0 spec.
2604 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002605 ASSERT(framebuffer);
2606
Jamie Madille7d80f32018-08-08 15:49:23 -04002607 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2608 {
2609 ASSERT(framebuffer);
2610 const FramebufferAttachment *dsAttachment =
2611 framebuffer->getStencilOrDepthStencilAttachment();
2612 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2613 ASSERT(stencilBits <= 8);
2614
2615 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2616 if (depthStencilState.stencilTest && stencilBits > 0)
2617 {
2618 GLuint maxStencilValue = (1 << stencilBits) - 1;
2619
2620 bool differentRefs =
2621 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2622 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2623 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2624 (depthStencilState.stencilBackWritemask & maxStencilValue);
2625 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2626 (depthStencilState.stencilBackMask & maxStencilValue);
2627
2628 if (differentRefs || differentWritemasks || differentMasks)
2629 {
2630 if (!extensions.webglCompatibility)
2631 {
2632 WARN() << "This ANGLE implementation does not support separate front/back "
2633 "stencil writemasks, reference values, or stencil mask values.";
2634 }
Jamie Madillb42162f2018-08-20 12:58:37 -04002635 return kErrorStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002636 }
2637 }
2638 }
2639
2640 if (!framebuffer->isComplete(context))
2641 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002642 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
2643 return kErrorDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002644 }
2645
2646 if (context->getStateCache().hasAnyEnabledClientAttrib())
2647 {
2648 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2649 {
2650 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2651 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2652 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2653 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madillb42162f2018-08-20 12:58:37 -04002654 return kErrorVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002655 }
2656
2657 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2658 {
2659 // This is an application error that would normally result in a crash, but we catch it
2660 // and return an error
Jamie Madillb42162f2018-08-20 12:58:37 -04002661 return kErrorVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002662 }
2663 }
2664
2665 // If we are running GLES1, there is no current program.
2666 if (context->getClientVersion() >= Version(2, 0))
2667 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002668 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002669 if (!program)
2670 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002671 return kErrorProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002672 }
2673
2674 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2675 // vertex shader stage or fragment shader stage is a undefined behaviour.
2676 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2677 // produce undefined result.
2678 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2679 !program->hasLinkedShaderStage(ShaderType::Fragment))
2680 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002681 return kErrorNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002682 }
2683
2684 if (!program->validateSamplers(nullptr, context->getCaps()))
2685 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002686 return kErrorTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002687 }
2688
2689 if (extensions.multiview)
2690 {
2691 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2692 const int framebufferNumViews = framebuffer->getNumViews();
2693 if (framebufferNumViews != programNumViews)
2694 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002695 return kErrorMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002696 }
2697
2698 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2699 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2700 framebufferNumViews > 1)
2701 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002702 return kErrorMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002703 }
2704
2705 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2706 state.isQueryActive(QueryType::TimeElapsed))
2707 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002708 return kErrorMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002709 }
2710 }
2711
2712 // Uniform buffer validation
2713 for (unsigned int uniformBlockIndex = 0;
2714 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2715 {
2716 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002717 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002718 const OffsetBindingPointer<Buffer> &uniformBuffer =
2719 state.getIndexedUniformBuffer(blockBinding);
2720
2721 if (uniformBuffer.get() == nullptr)
2722 {
2723 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002724 return kErrorUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002725 }
2726
2727 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2728 if (uniformBufferSize < uniformBlock.dataSize)
2729 {
2730 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002731 return kErrorUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002732 }
2733
2734 if (extensions.webglCompatibility &&
2735 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2736 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002737 return kErrorUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002738 }
2739 }
2740
2741 // Do some additonal WebGL-specific validation
2742 if (extensions.webglCompatibility)
2743 {
2744 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2745 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2746 transformFeedbackObject->buffersBoundForOtherUse())
2747 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002748 return kErrorTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002749 }
2750
2751 // Detect rendering feedback loops for WebGL.
2752 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2753 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002754 return kErrorFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002755 }
2756
2757 // Detect that the vertex shader input types match the attribute types
2758 if (!ValidateVertexShaderAttributeTypeMatch(context))
2759 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002760 return kErrorVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002761 }
2762
2763 // Detect that the color buffer types match the fragment shader output types
2764 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2765 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002766 return kErrorDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002767 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002768
2769 const VertexArray *vao = context->getGLState().getVertexArray();
2770 if (vao->hasTransformFeedbackBindingConflict(context))
2771 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002772 return kErrorVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002773 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002774 }
2775 }
2776
Jamie Madillb42162f2018-08-20 12:58:37 -04002777 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002778}
2779
Jamie Madill16e28fd2018-09-12 11:03:05 -04002780bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002781{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002782 const Extensions &extensions = context->getExtensions();
2783
Jamie Madill1aeb1312014-06-20 13:21:25 -04002784 switch (mode)
2785 {
Jamie Madill493f9572018-05-24 19:52:15 -04002786 case PrimitiveMode::Points:
2787 case PrimitiveMode::Lines:
2788 case PrimitiveMode::LineLoop:
2789 case PrimitiveMode::LineStrip:
2790 case PrimitiveMode::Triangles:
2791 case PrimitiveMode::TriangleStrip:
2792 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002793 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002794
Jamie Madill493f9572018-05-24 19:52:15 -04002795 case PrimitiveMode::LinesAdjacency:
2796 case PrimitiveMode::LineStripAdjacency:
2797 case PrimitiveMode::TrianglesAdjacency:
2798 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002799 if (!extensions.geometryShader)
2800 {
Jamie Madill610640f2018-11-21 17:28:41 -05002801 context->validationError(GL_INVALID_ENUM, kErrorGeometryShaderExtensionNotEnabled);
Jiawei Shaofccebff2018-03-08 13:51:02 +08002802 return false;
2803 }
2804 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002805 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002806 context->validationError(GL_INVALID_ENUM, kErrorInvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002807 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002808 }
2809
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002810 // If we are running GLES1, there is no current program.
2811 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002812 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002813 const State &state = context->getGLState();
2814
Jamie Madill785e8a02018-10-04 17:42:00 -04002815 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002816 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002817
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002818 // Do geometry shader specific validations
2819 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002820 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002821 if (!IsCompatibleDrawModeWithGeometryShader(
2822 mode, program->getGeometryShaderInputPrimitiveType()))
2823 {
Jamie Madill610640f2018-11-21 17:28:41 -05002824 context->validationError(GL_INVALID_OPERATION,
2825 kErrorIncompatibleDrawModeAgainstGeometryShader);
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002826 return false;
2827 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002828 }
2829 }
2830
Jamie Madill9fdaa492018-02-16 10:52:11 -05002831 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002832}
2833
Jamie Madill16e28fd2018-09-12 11:03:05 -04002834bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
2835{
2836 if (!context->getStateCache().isValidDrawMode(mode))
2837 {
2838 return ValidateDrawMode(context, mode);
2839 }
2840
2841 if (count < 0)
2842 {
Jamie Madill610640f2018-11-21 17:28:41 -05002843 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002844 return false;
2845 }
2846
2847 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2848 if (drawStatesError)
2849 {
2850 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2851
2852 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2853 // Incomplete.
2854 GLenum errorCode =
2855 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2856 : GL_INVALID_OPERATION);
Jamie Madill610640f2018-11-21 17:28:41 -05002857 context->validationError(errorCode, errorMessage);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002858 return false;
2859 }
2860
2861 return true;
2862}
2863
Jamie Madill5b772312018-03-08 20:28:32 -05002864bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002865 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002866 GLint first,
2867 GLsizei count,
2868 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002869{
Jamie Madillfd716582014-06-06 17:09:04 -04002870 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002871 {
Jamie Madill610640f2018-11-21 17:28:41 -05002872 context->validationError(GL_INVALID_VALUE, kErrorNegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002873 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002874 }
2875
Jamie Madill16e28fd2018-09-12 11:03:05 -04002876 if (count < 0)
2877 {
Jamie Madill610640f2018-11-21 17:28:41 -05002878 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Jamie Madill16e28fd2018-09-12 11:03:05 -04002879 return false;
2880 }
2881
Jamie Madill7f232932018-09-12 11:03:06 -04002882 const State &state = context->getGLState();
2883 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002884 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002885 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002886 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002887 if (!ValidateTransformFeedbackPrimitiveMode(context,
2888 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002889 {
Jamie Madill610640f2018-11-21 17:28:41 -05002890 context->validationError(GL_INVALID_OPERATION, kErrorInvalidDrawModeTransformFeedback);
James Darpinian30b604d2018-03-12 17:26:57 -07002891 return false;
2892 }
2893
2894 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2895 {
Jamie Madill610640f2018-11-21 17:28:41 -05002896 context->validationError(GL_INVALID_OPERATION, kErrorTransformFeedbackBufferTooSmall);
James Darpinian30b604d2018-03-12 17:26:57 -07002897 return false;
2898 }
Jamie Madillfd716582014-06-06 17:09:04 -04002899 }
2900
Jamie Madill16e28fd2018-09-12 11:03:05 -04002901 if (!context->getStateCache().isValidDrawMode(mode))
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002902 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002903 return ValidateDrawMode(context, mode);
2904 }
2905
2906 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2907 if (drawStatesError)
2908 {
2909 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2910
2911 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2912 // Incomplete.
2913 GLenum errorCode =
2914 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2915 : GL_INVALID_OPERATION);
Jamie Madill610640f2018-11-21 17:28:41 -05002916 context->validationError(errorCode, errorMessage);
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002917 return false;
2918 }
2919
Corentin Wallez71168a02016-12-19 15:11:18 -08002920 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002921 // - first < 0 has been checked as an error condition.
2922 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002923 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002924 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002925 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002926 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002927 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2928 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2929 {
Jamie Madill610640f2018-11-21 17:28:41 -05002930 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madill9fdaa492018-02-16 10:52:11 -05002931 return false;
2932 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002933
Jamie Madill2da53562018-08-01 11:34:47 -04002934 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002935 {
2936 return false;
2937 }
Jamie Madillfd716582014-06-06 17:09:04 -04002938 }
2939
2940 return true;
2941}
2942
He Yunchaoced53ae2016-11-29 15:00:51 +08002943bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002944 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002945 GLint first,
2946 GLsizei count,
2947 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002948{
Geoff Lang63c5a592017-09-27 14:08:16 -04002949 if (!context->getExtensions().instancedArrays)
2950 {
Jamie Madill610640f2018-11-21 17:28:41 -05002951 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04002952 return false;
2953 }
2954
Corentin Wallez170efbf2017-05-02 13:45:01 -04002955 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002956 {
2957 return false;
2958 }
2959
Corentin Wallez0dc97812017-06-22 14:38:44 -04002960 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002961}
2962
Jamie Madill493f9572018-05-24 19:52:15 -04002963bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, GLenum type)
Jamie Madillfd716582014-06-06 17:09:04 -04002964{
Jamie Madill250d33f2014-06-06 17:09:03 -04002965 switch (type)
2966 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002967 case GL_UNSIGNED_BYTE:
2968 case GL_UNSIGNED_SHORT:
2969 break;
2970 case GL_UNSIGNED_INT:
2971 if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
2972 {
Jamie Madill610640f2018-11-21 17:28:41 -05002973 context->validationError(GL_INVALID_ENUM, kErrorTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002974 return false;
2975 }
2976 break;
2977 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002978 context->validationError(GL_INVALID_ENUM, kErrorTypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002979 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002980 }
2981
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002982 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002983
Jamie Madill43da7c42018-08-01 11:34:49 -04002984 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002985 if (curTransformFeedback && curTransformFeedback->isActive() &&
2986 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002987 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002988 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2989 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2990 if (context->getExtensions().geometryShader)
2991 {
2992 if (!ValidateTransformFeedbackPrimitiveMode(
2993 context, curTransformFeedback->getPrimitiveMode(), mode))
2994 {
Jamie Madill610640f2018-11-21 17:28:41 -05002995 context->validationError(GL_INVALID_OPERATION,
2996 kErrorInvalidDrawModeTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002997 return false;
2998 }
2999 }
3000 else
3001 {
3002 // It is an invalid operation to call DrawElements, DrawRangeElements or
3003 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
3004 // 86)
Jamie Madill610640f2018-11-21 17:28:41 -05003005 context->validationError(GL_INVALID_OPERATION,
3006 kErrorUnsupportedDrawModeForTransformFeedback);
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003007 return false;
3008 }
Jamie Madill250d33f2014-06-06 17:09:03 -04003009 }
3010
Jiajia Qind9671222016-11-29 16:30:31 +08003011 return true;
3012}
3013
Jamie Madill5b772312018-03-08 20:28:32 -05003014bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003015 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003016 GLsizei count,
3017 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003018 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003019 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08003020{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003021 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003022 return false;
3023
3024 const State &state = context->getGLState();
3025
Corentin Wallez170efbf2017-05-02 13:45:01 -04003026 if (!ValidateDrawBase(context, mode, count))
3027 {
3028 return false;
3029 }
3030
Jamie Madill43da7c42018-08-01 11:34:49 -04003031 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003032 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003033
Jamie Madill43da7c42018-08-01 11:34:49 -04003034 GLuint typeBytes = GetTypeInfo(type).bytes;
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003035
3036 if (context->getExtensions().webglCompatibility)
3037 {
3038 ASSERT(isPow2(typeBytes) && typeBytes > 0);
3039 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3040 {
3041 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3042 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3043 // data type passed to the call, or an INVALID_OPERATION error is generated.
Jamie Madill610640f2018-11-21 17:28:41 -05003044 context->validationError(GL_INVALID_OPERATION, kErrorOffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003045 return false;
3046 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003047
3048 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3049 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3050 // error is generated.
3051 if (reinterpret_cast<intptr_t>(indices) < 0)
3052 {
Jamie Madill610640f2018-11-21 17:28:41 -05003053 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003054 return false;
3055 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003056 }
Jamie Madillcc73f242018-08-01 11:34:48 -04003057 else if (elementArrayBuffer && elementArrayBuffer->isMapped())
3058 {
3059 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3060 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the WebGL 2.0 API.
3061 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madill610640f2018-11-21 17:28:41 -05003062 context->validationError(GL_INVALID_OPERATION, "Index buffer is mapped.");
Jamie Madillcc73f242018-08-01 11:34:48 -04003063 return false;
3064 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003065
3066 if (context->getExtensions().webglCompatibility ||
3067 !context->getGLState().areClientArraysEnabled())
3068 {
Brandon Jones2a018152018-06-08 15:59:26 -07003069 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003070 {
3071 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003072 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3073 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Jamie Madill610640f2018-11-21 17:28:41 -05003074 context->validationError(GL_INVALID_OPERATION, kErrorMustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003075 return false;
3076 }
3077 }
3078
Jamie Madill9fdaa492018-02-16 10:52:11 -05003079 if (count > 0 && !elementArrayBuffer && !indices)
Jamie Madillae3000b2014-08-25 15:47:51 -04003080 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003081 // This is an application error that would normally result in a crash, but we catch it and
3082 // return an error
Jamie Madill610640f2018-11-21 17:28:41 -05003083 context->validationError(GL_INVALID_OPERATION, "No element array buffer and no pointer.");
Jamie Madill9fdaa492018-02-16 10:52:11 -05003084 return false;
3085 }
3086
3087 if (count > 0 && elementArrayBuffer)
3088 {
3089 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3090 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3091 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3092 constexpr uint64_t kMaxTypeSize = 8;
3093 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3094 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3095 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3096
3097 uint64_t typeSize = typeBytes;
3098 uint64_t elementCount = static_cast<uint64_t>(count);
3099 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3100
3101 // Doing the multiplication here is overflow-safe
3102 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3103
3104 // The offset can be any value, check for overflows
3105 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3106 if (elementDataSizeNoOffset > kUint64Max - offset)
Jamie Madillae3000b2014-08-25 15:47:51 -04003107 {
Jamie Madill610640f2018-11-21 17:28:41 -05003108 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madill9fdaa492018-02-16 10:52:11 -05003109 return false;
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003110 }
Jamie Madill9fdaa492018-02-16 10:52:11 -05003111
3112 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3113 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003114 {
Jamie Madill610640f2018-11-21 17:28:41 -05003115 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Jamie Madill9fdaa492018-02-16 10:52:11 -05003116 return false;
3117 }
3118
3119 ASSERT(isPow2(typeSize) && typeSize > 0);
3120 if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0)
3121 {
Jamie Madill610640f2018-11-21 17:28:41 -05003122 context->validationError(GL_INVALID_OPERATION, kErrorMismatchedByteCountType);
Geoff Langb1196682014-07-23 13:47:29 -04003123 return false;
Jamie Madillae3000b2014-08-25 15:47:51 -04003124 }
James Darpiniane8a93c62018-01-04 18:02:24 -08003125
3126 if (context->getExtensions().webglCompatibility &&
3127 elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
3128 {
Jamie Madill610640f2018-11-21 17:28:41 -05003129 context->validationError(GL_INVALID_OPERATION,
3130 kErrorElementArrayBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003131 return false;
3132 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003133 }
3134
Jamie Madill2da53562018-08-01 11:34:47 -04003135 if (!context->getExtensions().robustBufferAccessBehavior && count > 0 && primcount > 0)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003136 {
3137 // Use the parameter buffer to retrieve and cache the index range.
Jamie Madillc1fd7372018-10-26 22:48:39 -04003138 IndexRange indexRange;
3139 ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003140
3141 // If we use an index greater than our maximum supported index range, return an error.
3142 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
3143 // return an error if possible here.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003144 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003145 {
Jamie Madill610640f2018-11-21 17:28:41 -05003146 context->validationError(GL_INVALID_OPERATION, kErrorExceedsMaxElement);
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003147 return false;
3148 }
3149
Jamie Madill2da53562018-08-01 11:34:47 -04003150 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003151 {
3152 return false;
3153 }
3154
3155 // No op if there are no real indices in the index data (all are primitive restart).
Jamie Madill6f5444d2018-03-14 10:08:11 -04003156 return (indexRange.vertexIndexCount > 0);
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003157 }
3158
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003159 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003160}
3161
Jamie Madill5b772312018-03-08 20:28:32 -05003162bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003163 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003164 GLsizei count,
3165 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003166 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003167 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003168{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003169 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003170}
3171
Geoff Lang3edfe032015-09-04 16:38:24 -04003172bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003173 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003174 GLsizei count,
3175 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003176 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003177 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003178{
Geoff Lang63c5a592017-09-27 14:08:16 -04003179 if (!context->getExtensions().instancedArrays)
3180 {
Jamie Madill610640f2018-11-21 17:28:41 -05003181 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Lang63c5a592017-09-27 14:08:16 -04003182 return false;
3183 }
3184
Corentin Wallez170efbf2017-05-02 13:45:01 -04003185 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003186 {
3187 return false;
3188 }
3189
Corentin Wallez0dc97812017-06-22 14:38:44 -04003190 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003191}
3192
He Yunchaoced53ae2016-11-29 15:00:51 +08003193bool ValidateFramebufferTextureBase(Context *context,
3194 GLenum target,
3195 GLenum attachment,
3196 GLuint texture,
3197 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003198{
Geoff Lange8afa902017-09-27 15:00:43 -04003199 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003200 {
Jamie Madill610640f2018-11-21 17:28:41 -05003201 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003202 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003203 }
3204
3205 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003206 {
3207 return false;
3208 }
3209
Jamie Madill55ec3b12014-07-03 10:38:57 -04003210 if (texture != 0)
3211 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003212 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003213
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003214 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003215 {
Jamie Madill610640f2018-11-21 17:28:41 -05003216 context->validationError(GL_INVALID_OPERATION, kErrorMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04003217 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003218 }
3219
3220 if (level < 0)
3221 {
Jamie Madill610640f2018-11-21 17:28:41 -05003222 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04003223 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003224 }
3225 }
3226
Jamie Madill43da7c42018-08-01 11:34:49 -04003227 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003228 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003229
Jamie Madill84115c92015-04-23 15:00:07 -04003230 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003231 {
Jamie Madill610640f2018-11-21 17:28:41 -05003232 context->validationError(GL_INVALID_OPERATION, kErrorDefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003233 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003234 }
3235
3236 return true;
3237}
3238
Geoff Langb1196682014-07-23 13:47:29 -04003239bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003240{
3241 if (program == 0)
3242 {
Jamie Madill610640f2018-11-21 17:28:41 -05003243 context->validationError(GL_INVALID_VALUE, kErrorProgramDoesNotExist);
Geoff Langb1196682014-07-23 13:47:29 -04003244 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003245 }
3246
Jamie Madill43da7c42018-08-01 11:34:49 -04003247 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003248 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003249 {
3250 return false;
3251 }
3252
Jamie Madill0063c512014-08-25 15:47:53 -04003253 if (!programObject || !programObject->isLinked())
3254 {
Jamie Madill610640f2018-11-21 17:28:41 -05003255 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003256 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003257 }
3258
Geoff Lang7dd2e102014-11-10 15:19:26 -05003259 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003260 {
Jamie Madill610640f2018-11-21 17:28:41 -05003261 context->validationError(GL_INVALID_OPERATION, kErrorInvalidUniformLocation);
Geoff Langb1196682014-07-23 13:47:29 -04003262 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003263 }
3264
Jamie Madill0063c512014-08-25 15:47:53 -04003265 return true;
3266}
3267
Geoff Langf41d0ee2016-10-07 13:04:23 -04003268static bool ValidateSizedGetUniform(Context *context,
3269 GLuint program,
3270 GLint location,
3271 GLsizei bufSize,
3272 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003273{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003274 if (length)
3275 {
3276 *length = 0;
3277 }
3278
Jamie Madill78f41802014-08-25 15:47:55 -04003279 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003280 {
Jamie Madill78f41802014-08-25 15:47:55 -04003281 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003282 }
3283
Geoff Langf41d0ee2016-10-07 13:04:23 -04003284 if (bufSize < 0)
3285 {
Jamie Madill610640f2018-11-21 17:28:41 -05003286 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003287 return false;
3288 }
3289
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003290 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003291 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003292
Jamie Madill78f41802014-08-25 15:47:55 -04003293 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003294 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003295 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003296 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003297 {
Jamie Madill610640f2018-11-21 17:28:41 -05003298 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003299 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003300 }
3301
Geoff Langf41d0ee2016-10-07 13:04:23 -04003302 if (length)
3303 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003304 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003305 }
3306
Jamie Madill0063c512014-08-25 15:47:53 -04003307 return true;
3308}
3309
He Yunchaoced53ae2016-11-29 15:00:51 +08003310bool ValidateGetnUniformfvEXT(Context *context,
3311 GLuint program,
3312 GLint location,
3313 GLsizei bufSize,
3314 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003315{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003316 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003317}
3318
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003319bool ValidateGetnUniformfvRobustANGLE(Context *context,
3320 GLuint program,
3321 GLint location,
3322 GLsizei bufSize,
3323 GLsizei *length,
3324 GLfloat *params)
3325{
3326 UNIMPLEMENTED();
3327 return false;
3328}
3329
He Yunchaoced53ae2016-11-29 15:00:51 +08003330bool ValidateGetnUniformivEXT(Context *context,
3331 GLuint program,
3332 GLint location,
3333 GLsizei bufSize,
3334 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003335{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003336 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3337}
3338
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003339bool ValidateGetnUniformivRobustANGLE(Context *context,
3340 GLuint program,
3341 GLint location,
3342 GLsizei bufSize,
3343 GLsizei *length,
3344 GLint *params)
3345{
3346 UNIMPLEMENTED();
3347 return false;
3348}
3349
3350bool ValidateGetnUniformuivRobustANGLE(Context *context,
3351 GLuint program,
3352 GLint location,
3353 GLsizei bufSize,
3354 GLsizei *length,
3355 GLuint *params)
3356{
3357 UNIMPLEMENTED();
3358 return false;
3359}
3360
Geoff Langf41d0ee2016-10-07 13:04:23 -04003361bool ValidateGetUniformfvRobustANGLE(Context *context,
3362 GLuint program,
3363 GLint location,
3364 GLsizei bufSize,
3365 GLsizei *length,
3366 GLfloat *params)
3367{
3368 if (!ValidateRobustEntryPoint(context, bufSize))
3369 {
3370 return false;
3371 }
3372
Brandon Jonesd1049182018-03-28 10:02:20 -07003373 GLsizei writeLength = 0;
3374
Geoff Langf41d0ee2016-10-07 13:04:23 -04003375 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003376 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3377 {
3378 return false;
3379 }
3380
3381 SetRobustLengthParam(length, writeLength);
3382
3383 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003384}
3385
3386bool ValidateGetUniformivRobustANGLE(Context *context,
3387 GLuint program,
3388 GLint location,
3389 GLsizei bufSize,
3390 GLsizei *length,
3391 GLint *params)
3392{
3393 if (!ValidateRobustEntryPoint(context, bufSize))
3394 {
3395 return false;
3396 }
3397
Brandon Jonesd1049182018-03-28 10:02:20 -07003398 GLsizei writeLength = 0;
3399
Geoff Langf41d0ee2016-10-07 13:04:23 -04003400 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003401 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3402 {
3403 return false;
3404 }
3405
3406 SetRobustLengthParam(length, writeLength);
3407
3408 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003409}
3410
3411bool ValidateGetUniformuivRobustANGLE(Context *context,
3412 GLuint program,
3413 GLint location,
3414 GLsizei bufSize,
3415 GLsizei *length,
3416 GLuint *params)
3417{
3418 if (!ValidateRobustEntryPoint(context, bufSize))
3419 {
3420 return false;
3421 }
3422
3423 if (context->getClientMajorVersion() < 3)
3424 {
Jamie Madill610640f2018-11-21 17:28:41 -05003425 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003426 return false;
3427 }
3428
Brandon Jonesd1049182018-03-28 10:02:20 -07003429 GLsizei writeLength = 0;
3430
Geoff Langf41d0ee2016-10-07 13:04:23 -04003431 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003432 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3433 {
3434 return false;
3435 }
3436
3437 SetRobustLengthParam(length, writeLength);
3438
3439 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003440}
3441
He Yunchaoced53ae2016-11-29 15:00:51 +08003442bool ValidateDiscardFramebufferBase(Context *context,
3443 GLenum target,
3444 GLsizei numAttachments,
3445 const GLenum *attachments,
3446 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003447{
3448 if (numAttachments < 0)
3449 {
Jamie Madill610640f2018-11-21 17:28:41 -05003450 context->validationError(GL_INVALID_VALUE, kErrorNegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003451 return false;
3452 }
3453
3454 for (GLsizei i = 0; i < numAttachments; ++i)
3455 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003456 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003457 {
3458 if (defaultFramebuffer)
3459 {
Jamie Madill610640f2018-11-21 17:28:41 -05003460 context->validationError(GL_INVALID_ENUM,
3461 kErrorDefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003462 return false;
3463 }
3464
3465 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3466 {
Jamie Madill610640f2018-11-21 17:28:41 -05003467 context->validationError(GL_INVALID_OPERATION,
3468 "Requested color attachment is "
3469 "greater than the maximum supported "
3470 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003471 return false;
3472 }
3473 }
3474 else
3475 {
3476 switch (attachments[i])
3477 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003478 case GL_DEPTH_ATTACHMENT:
3479 case GL_STENCIL_ATTACHMENT:
3480 case GL_DEPTH_STENCIL_ATTACHMENT:
3481 if (defaultFramebuffer)
3482 {
Jamie Madill610640f2018-11-21 17:28:41 -05003483 context->validationError(GL_INVALID_ENUM,
3484 kErrorDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003485 return false;
3486 }
3487 break;
3488 case GL_COLOR:
3489 case GL_DEPTH:
3490 case GL_STENCIL:
3491 if (!defaultFramebuffer)
3492 {
Jamie Madill610640f2018-11-21 17:28:41 -05003493 context->validationError(GL_INVALID_ENUM,
3494 kErrorDefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003495 return false;
3496 }
3497 break;
3498 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003499 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003500 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003501 }
3502 }
3503 }
3504
3505 return true;
3506}
3507
Austin Kinross6ee1e782015-05-29 17:05:37 -07003508bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3509{
Jamie Madill007530e2017-12-28 14:27:04 -05003510 if (!context->getExtensions().debugMarker)
3511 {
3512 // The debug marker calls should not set error state
3513 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madill610640f2018-11-21 17:28:41 -05003514 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003515 return false;
3516 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003517
Jamie Madill007530e2017-12-28 14:27:04 -05003518 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003519 if (length < 0)
3520 {
3521 return false;
3522 }
3523
3524 if (marker == nullptr)
3525 {
3526 return false;
3527 }
3528
3529 return true;
3530}
3531
3532bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3533{
Jamie Madill007530e2017-12-28 14:27:04 -05003534 if (!context->getExtensions().debugMarker)
3535 {
3536 // The debug marker calls should not set error state
3537 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madill610640f2018-11-21 17:28:41 -05003538 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05003539 return false;
3540 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003541
Jamie Madill007530e2017-12-28 14:27:04 -05003542 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003543 if (length < 0)
3544 {
3545 return false;
3546 }
3547
3548 if (length > 0 && marker == nullptr)
3549 {
3550 return false;
3551 }
3552
3553 return true;
3554}
3555
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003556bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003557{
Geoff Langa8406172015-07-21 16:53:39 -04003558 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3559 {
Jamie Madill610640f2018-11-21 17:28:41 -05003560 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003561 return false;
3562 }
3563
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003564 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003565 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003566 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003567 if (!context->getExtensions().eglImage)
3568 {
Jamie Madill610640f2018-11-21 17:28:41 -05003569 context->validationError(GL_INVALID_ENUM,
3570 "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003571 }
3572 break;
3573
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003574 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003575 if (!context->getExtensions().eglImageExternal)
3576 {
Jamie Madill610640f2018-11-21 17:28:41 -05003577 context->validationError(GL_INVALID_ENUM,
3578 "GL_TEXTURE_EXTERNAL_OES texture target "
3579 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003580 }
Geoff Langa8406172015-07-21 16:53:39 -04003581 break;
3582
3583 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003584 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003585 return false;
3586 }
3587
Rafael Cintron05a449a2018-06-20 18:08:04 -07003588 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003589
Jamie Madill61e16b42017-06-19 11:13:23 -04003590 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003591 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003592 {
Jamie Madill610640f2018-11-21 17:28:41 -05003593 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003594 return false;
3595 }
3596
Jamie Madill007530e2017-12-28 14:27:04 -05003597 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003598 {
Jamie Madill610640f2018-11-21 17:28:41 -05003599 context->validationError(GL_INVALID_OPERATION,
3600 "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003601 return false;
3602 }
3603
Yuly Novikov2eb54072018-08-22 16:41:26 -04003604 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003605 {
Jamie Madill610640f2018-11-21 17:28:41 -05003606 context->validationError(GL_INVALID_OPERATION,
3607 "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003608 return false;
3609 }
3610
Geoff Langdcab33b2015-07-21 13:03:16 -04003611 return true;
3612}
3613
3614bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003615 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003616 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003617{
Geoff Langa8406172015-07-21 16:53:39 -04003618 if (!context->getExtensions().eglImage)
3619 {
Jamie Madill610640f2018-11-21 17:28:41 -05003620 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Geoff Langa8406172015-07-21 16:53:39 -04003621 return false;
3622 }
3623
3624 switch (target)
3625 {
3626 case GL_RENDERBUFFER:
3627 break;
3628
3629 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003630 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003631 return false;
3632 }
3633
Rafael Cintron05a449a2018-06-20 18:08:04 -07003634 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003635
Jamie Madill61e16b42017-06-19 11:13:23 -04003636 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003637 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003638 {
Jamie Madill610640f2018-11-21 17:28:41 -05003639 context->validationError(GL_INVALID_VALUE, "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003640 return false;
3641 }
3642
Yuly Novikov2eb54072018-08-22 16:41:26 -04003643 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003644 {
Jamie Madill610640f2018-11-21 17:28:41 -05003645 context->validationError(GL_INVALID_OPERATION,
3646 "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003647 return false;
3648 }
3649
Geoff Langdcab33b2015-07-21 13:03:16 -04003650 return true;
3651}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003652
3653bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3654{
Geoff Lang36167ab2015-12-07 10:27:14 -05003655 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003656 {
3657 // The default VAO should always exist
3658 ASSERT(array != 0);
Jamie Madill610640f2018-11-21 17:28:41 -05003659 context->validationError(GL_INVALID_OPERATION, kErrorInvalidVertexArray);
Austin Kinrossbc781f32015-10-26 09:27:38 -07003660 return false;
3661 }
3662
3663 return true;
3664}
3665
Geoff Langc5629752015-12-07 16:29:04 -05003666bool ValidateProgramBinaryBase(Context *context,
3667 GLuint program,
3668 GLenum binaryFormat,
3669 const void *binary,
3670 GLint length)
3671{
3672 Program *programObject = GetValidProgram(context, program);
3673 if (programObject == nullptr)
3674 {
3675 return false;
3676 }
3677
3678 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3679 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3680 programBinaryFormats.end())
3681 {
Jamie Madill610640f2018-11-21 17:28:41 -05003682 context->validationError(GL_INVALID_ENUM, "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003683 return false;
3684 }
3685
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003686 if (context->hasActiveTransformFeedback(program))
3687 {
3688 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05003689 context->validationError(GL_INVALID_OPERATION,
3690 "Cannot change program binary while program "
3691 "is associated with an active transform "
3692 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003693 return false;
3694 }
3695
Geoff Langc5629752015-12-07 16:29:04 -05003696 return true;
3697}
3698
3699bool ValidateGetProgramBinaryBase(Context *context,
3700 GLuint program,
3701 GLsizei bufSize,
3702 GLsizei *length,
3703 GLenum *binaryFormat,
3704 void *binary)
3705{
3706 Program *programObject = GetValidProgram(context, program);
3707 if (programObject == nullptr)
3708 {
3709 return false;
3710 }
3711
3712 if (!programObject->isLinked())
3713 {
Jamie Madill610640f2018-11-21 17:28:41 -05003714 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003715 return false;
3716 }
3717
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003718 if (context->getCaps().programBinaryFormats.empty())
3719 {
Jamie Madill610640f2018-11-21 17:28:41 -05003720 context->validationError(GL_INVALID_OPERATION, "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003721 return false;
3722 }
3723
Geoff Langc5629752015-12-07 16:29:04 -05003724 return true;
3725}
Jamie Madillc29968b2016-01-20 11:17:23 -05003726
Jamie Madill5b772312018-03-08 20:28:32 -05003727bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003728{
3729 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003730 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003731 {
Jamie Madill610640f2018-11-21 17:28:41 -05003732 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Brandon Jonesafa75152017-07-21 13:11:29 -07003733 return false;
3734 }
3735 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3736 {
Jamie Madill610640f2018-11-21 17:28:41 -05003737 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003738 return false;
3739 }
3740
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003741 ASSERT(context->getGLState().getDrawFramebuffer());
3742 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003743 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3744
3745 // This should come first before the check for the default frame buffer
3746 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3747 // rather than INVALID_OPERATION
3748 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3749 {
3750 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3751
3752 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003753 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3754 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003755 {
3756 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003757 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3758 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3759 // 3.1 is still a bit ambiguous about the error, but future specs are
3760 // expected to clarify that GL_INVALID_ENUM is the correct error.
Jamie Madill610640f2018-11-21 17:28:41 -05003761 context->validationError(GL_INVALID_ENUM, "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003762 return false;
3763 }
3764 else if (bufs[colorAttachment] >= maxColorAttachment)
3765 {
Jamie Madill610640f2018-11-21 17:28:41 -05003766 context->validationError(GL_INVALID_OPERATION,
3767 "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003768 return false;
3769 }
3770 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3771 frameBufferId != 0)
3772 {
3773 // INVALID_OPERATION-GL is bound to buffer and ith argument
3774 // is not COLOR_ATTACHMENTi or NONE
Jamie Madill610640f2018-11-21 17:28:41 -05003775 context->validationError(GL_INVALID_OPERATION,
3776 "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003777 return false;
3778 }
3779 }
3780
3781 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3782 // and n is not 1 or bufs is bound to value other than BACK and NONE
3783 if (frameBufferId == 0)
3784 {
3785 if (n != 1)
3786 {
Jamie Madill610640f2018-11-21 17:28:41 -05003787 context->validationError(GL_INVALID_OPERATION,
3788 "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003789 return false;
3790 }
3791
3792 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3793 {
Jamie Madill610640f2018-11-21 17:28:41 -05003794 context->validationError(
3795 GL_INVALID_OPERATION,
3796 "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003797 return false;
3798 }
3799 }
3800
3801 return true;
3802}
3803
Geoff Lang496c02d2016-10-20 11:38:11 -07003804bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003805 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003806 GLenum pname,
3807 GLsizei *length,
3808 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003809{
Geoff Lang496c02d2016-10-20 11:38:11 -07003810 if (length)
3811 {
3812 *length = 0;
3813 }
3814
3815 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3816 {
Jamie Madill610640f2018-11-21 17:28:41 -05003817 context->validationError(
3818 GL_INVALID_OPERATION,
3819 "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003820 return false;
3821 }
3822
Corentin Walleze4477002017-12-01 14:39:58 -05003823 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003824 {
Jamie Madill610640f2018-11-21 17:28:41 -05003825 context->validationError(GL_INVALID_ENUM, "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003826 return false;
3827 }
3828
Geoff Lang496c02d2016-10-20 11:38:11 -07003829 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003830 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003831 case GL_BUFFER_MAP_POINTER:
3832 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003833
Geoff Lang496c02d2016-10-20 11:38:11 -07003834 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003835 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003836 return false;
3837 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003838
3839 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3840 // target bound to zero generate an INVALID_OPERATION error."
3841 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003842 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003843 {
Jamie Madill610640f2018-11-21 17:28:41 -05003844 context->validationError(GL_INVALID_OPERATION,
3845 "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003846 return false;
3847 }
3848
Geoff Lang496c02d2016-10-20 11:38:11 -07003849 if (length)
3850 {
3851 *length = 1;
3852 }
3853
Olli Etuaho4f667482016-03-30 15:56:35 +03003854 return true;
3855}
3856
Corentin Wallez336129f2017-10-17 15:55:40 -04003857bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003858{
Corentin Walleze4477002017-12-01 14:39:58 -05003859 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003860 {
Jamie Madill610640f2018-11-21 17:28:41 -05003861 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003862 return false;
3863 }
3864
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003865 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003866
3867 if (buffer == nullptr || !buffer->isMapped())
3868 {
Jamie Madill610640f2018-11-21 17:28:41 -05003869 context->validationError(GL_INVALID_OPERATION, "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003870 return false;
3871 }
3872
3873 return true;
3874}
3875
3876bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003877 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003878 GLintptr offset,
3879 GLsizeiptr length,
3880 GLbitfield access)
3881{
Corentin Walleze4477002017-12-01 14:39:58 -05003882 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003883 {
Jamie Madill610640f2018-11-21 17:28:41 -05003884 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003885 return false;
3886 }
3887
Brandon Jones6cad5662017-06-14 13:25:13 -07003888 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003889 {
Jamie Madill610640f2018-11-21 17:28:41 -05003890 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003891 return false;
3892 }
3893
3894 if (length < 0)
3895 {
Jamie Madill610640f2018-11-21 17:28:41 -05003896 context->validationError(GL_INVALID_VALUE, kErrorNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003897 return false;
3898 }
3899
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003900 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003901
3902 if (!buffer)
3903 {
Jamie Madill610640f2018-11-21 17:28:41 -05003904 context->validationError(GL_INVALID_OPERATION, "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003905 return false;
3906 }
3907
3908 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003909 CheckedNumeric<size_t> checkedOffset(offset);
3910 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003911
Jamie Madille2e406c2016-06-02 13:04:10 -04003912 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003913 {
Jamie Madill610640f2018-11-21 17:28:41 -05003914 context->validationError(GL_INVALID_VALUE,
3915 "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003916 return false;
3917 }
3918
3919 // Check for invalid bits in the mask
3920 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3921 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3922 GL_MAP_UNSYNCHRONIZED_BIT;
3923
3924 if (access & ~(allAccessBits))
3925 {
Jamie Madill610640f2018-11-21 17:28:41 -05003926 context->validationError(GL_INVALID_VALUE, "Invalid access bits");
Olli Etuaho4f667482016-03-30 15:56:35 +03003927 return false;
3928 }
3929
3930 if (length == 0)
3931 {
Jamie Madill610640f2018-11-21 17:28:41 -05003932 context->validationError(GL_INVALID_OPERATION, "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003933 return false;
3934 }
3935
3936 if (buffer->isMapped())
3937 {
Jamie Madill610640f2018-11-21 17:28:41 -05003938 context->validationError(GL_INVALID_OPERATION, "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003939 return false;
3940 }
3941
3942 // Check for invalid bit combinations
3943 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3944 {
Jamie Madill610640f2018-11-21 17:28:41 -05003945 context->validationError(GL_INVALID_OPERATION,
3946 "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003947 return false;
3948 }
3949
3950 GLbitfield writeOnlyBits =
3951 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3952
3953 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3954 {
Jamie Madill610640f2018-11-21 17:28:41 -05003955 context->validationError(GL_INVALID_OPERATION,
3956 "Invalid access bits when mapping buffer for reading");
Olli Etuaho4f667482016-03-30 15:56:35 +03003957 return false;
3958 }
3959
3960 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3961 {
Jamie Madill610640f2018-11-21 17:28:41 -05003962 context->validationError(
3963 GL_INVALID_OPERATION,
3964 "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003965 return false;
3966 }
Geoff Lang79f71042017-08-14 16:43:43 -04003967
3968 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003969}
3970
3971bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003972 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003973 GLintptr offset,
3974 GLsizeiptr length)
3975{
Brandon Jones6cad5662017-06-14 13:25:13 -07003976 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003977 {
Jamie Madill610640f2018-11-21 17:28:41 -05003978 context->validationError(GL_INVALID_VALUE, kErrorNegativeOffset);
Brandon Jones6cad5662017-06-14 13:25:13 -07003979 return false;
3980 }
3981
3982 if (length < 0)
3983 {
Jamie Madill610640f2018-11-21 17:28:41 -05003984 context->validationError(GL_INVALID_VALUE, kErrorNegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003985 return false;
3986 }
3987
Corentin Walleze4477002017-12-01 14:39:58 -05003988 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003989 {
Jamie Madill610640f2018-11-21 17:28:41 -05003990 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003991 return false;
3992 }
3993
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003994 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003995
3996 if (buffer == nullptr)
3997 {
Jamie Madill610640f2018-11-21 17:28:41 -05003998 context->validationError(GL_INVALID_OPERATION, "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003999 return false;
4000 }
4001
4002 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
4003 {
Jamie Madill610640f2018-11-21 17:28:41 -05004004 context->validationError(GL_INVALID_OPERATION,
4005 "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004006 return false;
4007 }
4008
4009 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04004010 CheckedNumeric<size_t> checkedOffset(offset);
4011 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03004012
Jamie Madille2e406c2016-06-02 13:04:10 -04004013 if (!checkedSize.IsValid() ||
4014 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03004015 {
Jamie Madill610640f2018-11-21 17:28:41 -05004016 context->validationError(GL_INVALID_VALUE,
4017 "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004018 return false;
4019 }
4020
4021 return true;
4022}
4023
Olli Etuaho41997e72016-03-10 13:38:39 +02004024bool ValidateGenOrDelete(Context *context, GLint n)
4025{
4026 if (n < 0)
4027 {
Jamie Madill610640f2018-11-21 17:28:41 -05004028 context->validationError(GL_INVALID_VALUE, kErrorNegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004029 return false;
4030 }
4031 return true;
4032}
4033
Jamie Madill5b772312018-03-08 20:28:32 -05004034bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004035{
4036 if (!context->getExtensions().robustClientMemory)
4037 {
Jamie Madill610640f2018-11-21 17:28:41 -05004038 context->validationError(GL_INVALID_OPERATION,
4039 "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004040 return false;
4041 }
4042
4043 if (bufSize < 0)
4044 {
Jamie Madill610640f2018-11-21 17:28:41 -05004045 context->validationError(GL_INVALID_VALUE, kErrorNegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004046 return false;
4047 }
4048
4049 return true;
4050}
4051
Jamie Madill5b772312018-03-08 20:28:32 -05004052bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004053{
4054 if (bufSize < numParams)
4055 {
Jamie Madill610640f2018-11-21 17:28:41 -05004056 context->validationError(GL_INVALID_OPERATION,
4057 "More parameters are required than were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004058 return false;
4059 }
4060
4061 return true;
4062}
4063
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004064bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004065 GLenum target,
4066 GLenum attachment,
4067 GLenum pname,
4068 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004069{
Geoff Lange8afa902017-09-27 15:00:43 -04004070 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004071 {
Jamie Madill610640f2018-11-21 17:28:41 -05004072 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004073 return false;
4074 }
4075
4076 int clientVersion = context->getClientMajorVersion();
4077
4078 switch (pname)
4079 {
4080 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4081 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4082 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4083 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4084 break;
4085
Martin Radeve5285d22017-07-14 16:23:53 +03004086 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4087 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4088 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4089 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4090 if (clientVersion < 3 || !context->getExtensions().multiview)
4091 {
Jamie Madill610640f2018-11-21 17:28:41 -05004092 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Martin Radeve5285d22017-07-14 16:23:53 +03004093 return false;
4094 }
4095 break;
4096
Geoff Langff5b2d52016-09-07 11:32:23 -04004097 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4098 if (clientVersion < 3 && !context->getExtensions().sRGB)
4099 {
Jamie Madill610640f2018-11-21 17:28:41 -05004100 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004101 return false;
4102 }
4103 break;
4104
4105 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4106 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4107 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4108 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4109 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4110 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4111 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4112 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4113 if (clientVersion < 3)
4114 {
Jamie Madill610640f2018-11-21 17:28:41 -05004115 context->validationError(GL_INVALID_ENUM, kErrorES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004116 return false;
4117 }
4118 break;
4119
Jiawei Shaoa8802472018-05-28 11:17:47 +08004120 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4121 if (!context->getExtensions().geometryShader)
4122 {
Jamie Madill610640f2018-11-21 17:28:41 -05004123 context->validationError(GL_INVALID_ENUM, kErrorGeometryShaderExtensionNotEnabled);
Jiawei Shaoa8802472018-05-28 11:17:47 +08004124 return false;
4125 }
4126 break;
4127
Geoff Langff5b2d52016-09-07 11:32:23 -04004128 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004129 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Geoff Langff5b2d52016-09-07 11:32:23 -04004130 return false;
4131 }
4132
4133 // Determine if the attachment is a valid enum
4134 switch (attachment)
4135 {
4136 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004137 case GL_DEPTH:
4138 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004139 if (clientVersion < 3)
4140 {
Jamie Madill610640f2018-11-21 17:28:41 -05004141 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004142 return false;
4143 }
4144 break;
4145
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004146 case GL_DEPTH_STENCIL_ATTACHMENT:
4147 if (clientVersion < 3 && !context->isWebGL1())
4148 {
Jamie Madill610640f2018-11-21 17:28:41 -05004149 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004150 return false;
4151 }
4152 break;
4153
Geoff Langfa125c92017-10-24 13:01:46 -04004154 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004155 case GL_DEPTH_ATTACHMENT:
4156 case GL_STENCIL_ATTACHMENT:
4157 break;
4158
4159 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004160 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4161 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004162 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4163 {
Jamie Madill610640f2018-11-21 17:28:41 -05004164 context->validationError(GL_INVALID_ENUM, kErrorInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004165 return false;
4166 }
4167 break;
4168 }
4169
4170 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4171 ASSERT(framebuffer);
4172
4173 if (framebuffer->id() == 0)
4174 {
4175 if (clientVersion < 3)
4176 {
Jamie Madill610640f2018-11-21 17:28:41 -05004177 context->validationError(GL_INVALID_OPERATION, kErrorDefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004178 return false;
4179 }
4180
4181 switch (attachment)
4182 {
4183 case GL_BACK:
4184 case GL_DEPTH:
4185 case GL_STENCIL:
4186 break;
4187
4188 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004189 context->validationError(GL_INVALID_OPERATION, kErrorInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004190 return false;
4191 }
4192 }
4193 else
4194 {
4195 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4196 {
4197 // Valid attachment query
4198 }
4199 else
4200 {
4201 switch (attachment)
4202 {
4203 case GL_DEPTH_ATTACHMENT:
4204 case GL_STENCIL_ATTACHMENT:
4205 break;
4206
4207 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004208 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004209 {
Jamie Madill610640f2018-11-21 17:28:41 -05004210 context->validationError(GL_INVALID_OPERATION, kErrorInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004211 return false;
4212 }
4213 break;
4214
4215 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004216 context->validationError(GL_INVALID_OPERATION, kErrorInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004217 return false;
4218 }
4219 }
4220 }
4221
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004222 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004223 if (attachmentObject)
4224 {
4225 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4226 attachmentObject->type() == GL_TEXTURE ||
4227 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4228
4229 switch (pname)
4230 {
4231 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4232 if (attachmentObject->type() != GL_RENDERBUFFER &&
4233 attachmentObject->type() != GL_TEXTURE)
4234 {
Jamie Madill610640f2018-11-21 17:28:41 -05004235 context->validationError(GL_INVALID_ENUM,
4236 kErrorFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004237 return false;
4238 }
4239 break;
4240
4241 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4242 if (attachmentObject->type() != GL_TEXTURE)
4243 {
Jamie Madill610640f2018-11-21 17:28:41 -05004244 context->validationError(GL_INVALID_ENUM,
4245 kErrorFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004246 return false;
4247 }
4248 break;
4249
4250 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4251 if (attachmentObject->type() != GL_TEXTURE)
4252 {
Jamie Madill610640f2018-11-21 17:28:41 -05004253 context->validationError(GL_INVALID_ENUM,
4254 kErrorFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004255 return false;
4256 }
4257 break;
4258
4259 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4260 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4261 {
Jamie Madill610640f2018-11-21 17:28:41 -05004262 context->validationError(GL_INVALID_OPERATION, kErrorInvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004263 return false;
4264 }
4265 break;
4266
4267 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4268 if (attachmentObject->type() != GL_TEXTURE)
4269 {
Jamie Madill610640f2018-11-21 17:28:41 -05004270 context->validationError(GL_INVALID_ENUM,
4271 kErrorFramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004272 return false;
4273 }
4274 break;
4275
4276 default:
4277 break;
4278 }
4279 }
4280 else
4281 {
4282 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4283 // is NONE, then querying any other pname will generate INVALID_ENUM.
4284
4285 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4286 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4287 // INVALID_OPERATION for all other pnames
4288
4289 switch (pname)
4290 {
4291 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4292 break;
4293
4294 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4295 if (clientVersion < 3)
4296 {
Jamie Madill610640f2018-11-21 17:28:41 -05004297 context->validationError(GL_INVALID_ENUM,
4298 kErrorInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004299 return false;
4300 }
4301 break;
4302
4303 default:
4304 if (clientVersion < 3)
4305 {
Jamie Madill610640f2018-11-21 17:28:41 -05004306 context->validationError(GL_INVALID_ENUM,
4307 kErrorInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004308 return false;
4309 }
4310 else
4311 {
Jamie Madill610640f2018-11-21 17:28:41 -05004312 context->validationError(GL_INVALID_OPERATION,
4313 kErrorInvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004314 return false;
4315 }
4316 }
4317 }
4318
Martin Radeve5285d22017-07-14 16:23:53 +03004319 if (numParams)
4320 {
4321 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4322 {
4323 // Only when the viewport offsets are queried we can have a varying number of output
4324 // parameters.
4325 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4326 *numParams = numViews * 2;
4327 }
4328 else
4329 {
4330 // For all other queries we can have only one output parameter.
4331 *numParams = 1;
4332 }
4333 }
4334
Geoff Langff5b2d52016-09-07 11:32:23 -04004335 return true;
4336}
4337
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004338bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004339 GLenum target,
4340 GLenum attachment,
4341 GLenum pname,
4342 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004343 GLsizei *length,
4344 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004345{
4346 if (!ValidateRobustEntryPoint(context, bufSize))
4347 {
4348 return false;
4349 }
4350
Brandon Jonesd1049182018-03-28 10:02:20 -07004351 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004352 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004353 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004354 {
4355 return false;
4356 }
4357
Brandon Jonesd1049182018-03-28 10:02:20 -07004358 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004359 {
4360 return false;
4361 }
4362
Brandon Jonesd1049182018-03-28 10:02:20 -07004363 SetRobustLengthParam(length, numParams);
4364
Geoff Langff5b2d52016-09-07 11:32:23 -04004365 return true;
4366}
4367
Jamie Madill5b772312018-03-08 20:28:32 -05004368bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004369 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004370 GLenum pname,
4371 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004372 GLsizei *length,
4373 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004374{
4375 if (!ValidateRobustEntryPoint(context, bufSize))
4376 {
4377 return false;
4378 }
4379
Brandon Jonesd1049182018-03-28 10:02:20 -07004380 GLsizei numParams = 0;
4381
4382 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004383 {
4384 return false;
4385 }
4386
Brandon Jonesd1049182018-03-28 10:02:20 -07004387 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004388 {
4389 return false;
4390 }
4391
Brandon Jonesd1049182018-03-28 10:02:20 -07004392 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004393 return true;
4394}
4395
Jamie Madill5b772312018-03-08 20:28:32 -05004396bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004397 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004398 GLenum pname,
4399 GLsizei bufSize,
4400 GLsizei *length,
4401 GLint64 *params)
4402{
Brandon Jonesd1049182018-03-28 10:02:20 -07004403 GLsizei numParams = 0;
4404
Geoff Langebebe1c2016-10-14 12:01:31 -04004405 if (!ValidateRobustEntryPoint(context, bufSize))
4406 {
4407 return false;
4408 }
4409
Brandon Jonesd1049182018-03-28 10:02:20 -07004410 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004411 {
4412 return false;
4413 }
4414
Brandon Jonesd1049182018-03-28 10:02:20 -07004415 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004416 {
4417 return false;
4418 }
4419
Brandon Jonesd1049182018-03-28 10:02:20 -07004420 SetRobustLengthParam(length, numParams);
4421
Geoff Langff5b2d52016-09-07 11:32:23 -04004422 return true;
4423}
4424
Jamie Madill5b772312018-03-08 20:28:32 -05004425bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004426{
4427 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004428 if (numParams)
4429 {
4430 *numParams = 1;
4431 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004432
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004433 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4434 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4435 ? GetValidProgramNoResolve(context, program)
4436 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004437 if (!programObject)
4438 {
4439 return false;
4440 }
4441
4442 switch (pname)
4443 {
4444 case GL_DELETE_STATUS:
4445 case GL_LINK_STATUS:
4446 case GL_VALIDATE_STATUS:
4447 case GL_INFO_LOG_LENGTH:
4448 case GL_ATTACHED_SHADERS:
4449 case GL_ACTIVE_ATTRIBUTES:
4450 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4451 case GL_ACTIVE_UNIFORMS:
4452 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4453 break;
4454
4455 case GL_PROGRAM_BINARY_LENGTH:
4456 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4457 {
Jamie Madill610640f2018-11-21 17:28:41 -05004458 context->validationError(GL_INVALID_ENUM,
4459 "Querying GL_PROGRAM_BINARY_LENGTH "
4460 "requires GL_OES_get_program_binary or "
4461 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004462 return false;
4463 }
4464 break;
4465
4466 case GL_ACTIVE_UNIFORM_BLOCKS:
4467 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4468 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4469 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4470 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4471 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4472 if (context->getClientMajorVersion() < 3)
4473 {
Jamie Madill610640f2018-11-21 17:28:41 -05004474 context->validationError(GL_INVALID_ENUM, kErrorES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004475 return false;
4476 }
4477 break;
4478
Yunchao He61afff12017-03-14 15:34:03 +08004479 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004480 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004481 if (context->getClientVersion() < Version(3, 1))
4482 {
Jamie Madill610640f2018-11-21 17:28:41 -05004483 context->validationError(GL_INVALID_ENUM, kErrorES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004484 return false;
4485 }
4486 break;
4487
Jiawei Shao6ae51612018-02-23 14:03:25 +08004488 case GL_COMPUTE_WORK_GROUP_SIZE:
4489 if (context->getClientVersion() < Version(3, 1))
4490 {
Jamie Madill610640f2018-11-21 17:28:41 -05004491 context->validationError(GL_INVALID_ENUM, kErrorES31Required);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004492 return false;
4493 }
4494
4495 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4496 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4497 // program which has not been linked successfully, or which does not contain objects to
4498 // form a compute shader.
4499 if (!programObject->isLinked())
4500 {
Jamie Madill610640f2018-11-21 17:28:41 -05004501 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004502 return false;
4503 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004504 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004505 {
Jamie Madill610640f2018-11-21 17:28:41 -05004506 context->validationError(GL_INVALID_OPERATION, kErrorNoActiveComputeShaderStage);
Jiawei Shao6ae51612018-02-23 14:03:25 +08004507 return false;
4508 }
4509 break;
4510
Jiawei Shao447bfac2018-03-14 14:23:40 +08004511 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4512 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4513 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4514 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4515 if (!context->getExtensions().geometryShader)
4516 {
Jamie Madill610640f2018-11-21 17:28:41 -05004517 context->validationError(GL_INVALID_ENUM, kErrorGeometryShaderExtensionNotEnabled);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004518 return false;
4519 }
4520
4521 // [EXT_geometry_shader] Chapter 7.12
4522 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4523 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4524 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4525 // successfully, or which does not contain objects to form a geometry shader.
4526 if (!programObject->isLinked())
4527 {
Jamie Madill610640f2018-11-21 17:28:41 -05004528 context->validationError(GL_INVALID_OPERATION, kErrorProgramNotLinked);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004529 return false;
4530 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004531 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004532 {
Jamie Madill610640f2018-11-21 17:28:41 -05004533 context->validationError(GL_INVALID_OPERATION, kErrorNoActiveGeometryShaderStage);
Jiawei Shao447bfac2018-03-14 14:23:40 +08004534 return false;
4535 }
4536 break;
4537
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004538 case GL_COMPLETION_STATUS_KHR:
4539 if (!context->getExtensions().parallelShaderCompile)
4540 {
Jamie Madill610640f2018-11-21 17:28:41 -05004541 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004542 return false;
4543 }
4544 break;
4545
Geoff Langff5b2d52016-09-07 11:32:23 -04004546 default:
Jamie Madill610640f2018-11-21 17:28:41 -05004547 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004548 return false;
4549 }
4550
4551 return true;
4552}
4553
4554bool ValidateGetProgramivRobustANGLE(Context *context,
4555 GLuint program,
4556 GLenum pname,
4557 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004558 GLsizei *length,
4559 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004560{
4561 if (!ValidateRobustEntryPoint(context, bufSize))
4562 {
4563 return false;
4564 }
4565
Brandon Jonesd1049182018-03-28 10:02:20 -07004566 GLsizei numParams = 0;
4567
4568 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004569 {
4570 return false;
4571 }
4572
Brandon Jonesd1049182018-03-28 10:02:20 -07004573 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004574 {
4575 return false;
4576 }
4577
Brandon Jonesd1049182018-03-28 10:02:20 -07004578 SetRobustLengthParam(length, numParams);
4579
Geoff Langff5b2d52016-09-07 11:32:23 -04004580 return true;
4581}
4582
Geoff Lang740d9022016-10-07 11:20:52 -04004583bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4584 GLenum target,
4585 GLenum pname,
4586 GLsizei bufSize,
4587 GLsizei *length,
4588 GLint *params)
4589{
4590 if (!ValidateRobustEntryPoint(context, bufSize))
4591 {
4592 return false;
4593 }
4594
Brandon Jonesd1049182018-03-28 10:02:20 -07004595 GLsizei numParams = 0;
4596
4597 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004598 {
4599 return false;
4600 }
4601
Brandon Jonesd1049182018-03-28 10:02:20 -07004602 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004603 {
4604 return false;
4605 }
4606
Brandon Jonesd1049182018-03-28 10:02:20 -07004607 SetRobustLengthParam(length, numParams);
4608
Geoff Lang740d9022016-10-07 11:20:52 -04004609 return true;
4610}
4611
Geoff Langd7d0ed32016-10-07 11:33:51 -04004612bool ValidateGetShaderivRobustANGLE(Context *context,
4613 GLuint shader,
4614 GLenum pname,
4615 GLsizei bufSize,
4616 GLsizei *length,
4617 GLint *params)
4618{
4619 if (!ValidateRobustEntryPoint(context, bufSize))
4620 {
4621 return false;
4622 }
4623
Brandon Jonesd1049182018-03-28 10:02:20 -07004624 GLsizei numParams = 0;
4625
4626 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004627 {
4628 return false;
4629 }
4630
Brandon Jonesd1049182018-03-28 10:02:20 -07004631 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004632 {
4633 return false;
4634 }
4635
Brandon Jonesd1049182018-03-28 10:02:20 -07004636 SetRobustLengthParam(length, numParams);
4637
Geoff Langd7d0ed32016-10-07 11:33:51 -04004638 return true;
4639}
4640
Geoff Langc1984ed2016-10-07 12:41:00 -04004641bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004642 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004643 GLenum pname,
4644 GLsizei bufSize,
4645 GLsizei *length,
4646 GLfloat *params)
4647{
4648 if (!ValidateRobustEntryPoint(context, bufSize))
4649 {
4650 return false;
4651 }
4652
Brandon Jonesd1049182018-03-28 10:02:20 -07004653 GLsizei numParams = 0;
4654
4655 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004656 {
4657 return false;
4658 }
4659
Brandon Jonesd1049182018-03-28 10:02:20 -07004660 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004661 {
4662 return false;
4663 }
4664
Brandon Jonesd1049182018-03-28 10:02:20 -07004665 SetRobustLengthParam(length, numParams);
4666
Geoff Langc1984ed2016-10-07 12:41:00 -04004667 return true;
4668}
4669
Geoff Langc1984ed2016-10-07 12:41:00 -04004670bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004671 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004672 GLenum pname,
4673 GLsizei bufSize,
4674 GLsizei *length,
4675 GLint *params)
4676{
Brandon Jonesd1049182018-03-28 10:02:20 -07004677
Geoff Langc1984ed2016-10-07 12:41:00 -04004678 if (!ValidateRobustEntryPoint(context, bufSize))
4679 {
4680 return false;
4681 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004682 GLsizei numParams = 0;
4683 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004684 {
4685 return false;
4686 }
4687
Brandon Jonesd1049182018-03-28 10:02:20 -07004688 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004689 {
4690 return false;
4691 }
4692
Brandon Jonesd1049182018-03-28 10:02:20 -07004693 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004694 return true;
4695}
4696
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004697bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4698 TextureType target,
4699 GLenum pname,
4700 GLsizei bufSize,
4701 GLsizei *length,
4702 GLint *params)
4703{
4704 UNIMPLEMENTED();
4705 return false;
4706}
4707
4708bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4709 TextureType target,
4710 GLenum pname,
4711 GLsizei bufSize,
4712 GLsizei *length,
4713 GLuint *params)
4714{
4715 UNIMPLEMENTED();
4716 return false;
4717}
4718
Geoff Langc1984ed2016-10-07 12:41:00 -04004719bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004720 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004721 GLenum pname,
4722 GLsizei bufSize,
4723 const GLfloat *params)
4724{
4725 if (!ValidateRobustEntryPoint(context, bufSize))
4726 {
4727 return false;
4728 }
4729
Till Rathmannb8543632018-10-02 19:46:14 +02004730 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004731}
4732
Geoff Langc1984ed2016-10-07 12:41:00 -04004733bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004734 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004735 GLenum pname,
4736 GLsizei bufSize,
4737 const GLint *params)
4738{
4739 if (!ValidateRobustEntryPoint(context, bufSize))
4740 {
4741 return false;
4742 }
4743
Till Rathmannb8543632018-10-02 19:46:14 +02004744 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004745}
4746
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004747bool ValidateTexParameterIivRobustANGLE(Context *context,
4748 TextureType target,
4749 GLenum pname,
4750 GLsizei bufSize,
4751 const GLint *params)
4752{
4753 UNIMPLEMENTED();
4754 return false;
4755}
4756
4757bool ValidateTexParameterIuivRobustANGLE(Context *context,
4758 TextureType target,
4759 GLenum pname,
4760 GLsizei bufSize,
4761 const GLuint *params)
4762{
4763 UNIMPLEMENTED();
4764 return false;
4765}
4766
Geoff Langc1984ed2016-10-07 12:41:00 -04004767bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4768 GLuint sampler,
4769 GLenum pname,
Jamie Madill778bf092018-11-14 09:54:36 -05004770 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004771 GLsizei *length,
4772 GLfloat *params)
4773{
4774 if (!ValidateRobustEntryPoint(context, bufSize))
4775 {
4776 return false;
4777 }
4778
Brandon Jonesd1049182018-03-28 10:02:20 -07004779 GLsizei numParams = 0;
4780
4781 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004782 {
4783 return false;
4784 }
4785
Brandon Jonesd1049182018-03-28 10:02:20 -07004786 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004787 {
4788 return false;
4789 }
4790
Brandon Jonesd1049182018-03-28 10:02:20 -07004791 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004792 return true;
4793}
4794
Geoff Langc1984ed2016-10-07 12:41:00 -04004795bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4796 GLuint sampler,
4797 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004798 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004799 GLsizei *length,
4800 GLint *params)
4801{
4802 if (!ValidateRobustEntryPoint(context, bufSize))
4803 {
4804 return false;
4805 }
4806
Brandon Jonesd1049182018-03-28 10:02:20 -07004807 GLsizei numParams = 0;
4808
4809 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004810 {
4811 return false;
4812 }
4813
Brandon Jonesd1049182018-03-28 10:02:20 -07004814 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004815 {
4816 return false;
4817 }
4818
Brandon Jonesd1049182018-03-28 10:02:20 -07004819 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004820 return true;
4821}
4822
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004823bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4824 GLuint sampler,
4825 GLenum pname,
4826 GLsizei bufSize,
4827 GLsizei *length,
4828 GLint *params)
4829{
4830 UNIMPLEMENTED();
4831 return false;
4832}
4833
4834bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4835 GLuint sampler,
4836 GLenum pname,
4837 GLsizei bufSize,
4838 GLsizei *length,
4839 GLuint *params)
4840{
4841 UNIMPLEMENTED();
4842 return false;
4843}
4844
Geoff Langc1984ed2016-10-07 12:41:00 -04004845bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4846 GLuint sampler,
4847 GLenum pname,
4848 GLsizei bufSize,
4849 const GLfloat *params)
4850{
4851 if (!ValidateRobustEntryPoint(context, bufSize))
4852 {
4853 return false;
4854 }
4855
Till Rathmannb8543632018-10-02 19:46:14 +02004856 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004857}
4858
Geoff Langc1984ed2016-10-07 12:41:00 -04004859bool ValidateSamplerParameterivRobustANGLE(Context *context,
4860 GLuint sampler,
4861 GLenum pname,
4862 GLsizei bufSize,
4863 const GLint *params)
4864{
4865 if (!ValidateRobustEntryPoint(context, bufSize))
4866 {
4867 return false;
4868 }
4869
Till Rathmannb8543632018-10-02 19:46:14 +02004870 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004871}
4872
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004873bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4874 GLuint sampler,
4875 GLenum pname,
4876 GLsizei bufSize,
4877 const GLint *param)
4878{
4879 UNIMPLEMENTED();
4880 return false;
4881}
4882
4883bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4884 GLuint sampler,
4885 GLenum pname,
4886 GLsizei bufSize,
4887 const GLuint *param)
4888{
4889 UNIMPLEMENTED();
4890 return false;
4891}
4892
Geoff Lang0b031062016-10-13 14:30:04 -04004893bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4894 GLuint index,
4895 GLenum pname,
4896 GLsizei bufSize,
4897 GLsizei *length,
4898 GLfloat *params)
4899{
4900 if (!ValidateRobustEntryPoint(context, bufSize))
4901 {
4902 return false;
4903 }
4904
Brandon Jonesd1049182018-03-28 10:02:20 -07004905 GLsizei writeLength = 0;
4906
4907 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004908 {
4909 return false;
4910 }
4911
Brandon Jonesd1049182018-03-28 10:02:20 -07004912 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004913 {
4914 return false;
4915 }
4916
Brandon Jonesd1049182018-03-28 10:02:20 -07004917 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004918 return true;
4919}
4920
Geoff Lang0b031062016-10-13 14:30:04 -04004921bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4922 GLuint index,
4923 GLenum pname,
4924 GLsizei bufSize,
4925 GLsizei *length,
4926 GLint *params)
4927{
4928 if (!ValidateRobustEntryPoint(context, bufSize))
4929 {
4930 return false;
4931 }
4932
Brandon Jonesd1049182018-03-28 10:02:20 -07004933 GLsizei writeLength = 0;
4934
4935 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004936 {
4937 return false;
4938 }
4939
Brandon Jonesd1049182018-03-28 10:02:20 -07004940 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004941 {
4942 return false;
4943 }
4944
Brandon Jonesd1049182018-03-28 10:02:20 -07004945 SetRobustLengthParam(length, writeLength);
4946
Geoff Lang0b031062016-10-13 14:30:04 -04004947 return true;
4948}
4949
Geoff Lang0b031062016-10-13 14:30:04 -04004950bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4951 GLuint index,
4952 GLenum pname,
4953 GLsizei bufSize,
4954 GLsizei *length,
4955 void **pointer)
4956{
4957 if (!ValidateRobustEntryPoint(context, bufSize))
4958 {
4959 return false;
4960 }
4961
Brandon Jonesd1049182018-03-28 10:02:20 -07004962 GLsizei writeLength = 0;
4963
4964 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004965 {
4966 return false;
4967 }
4968
Brandon Jonesd1049182018-03-28 10:02:20 -07004969 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004970 {
4971 return false;
4972 }
4973
Brandon Jonesd1049182018-03-28 10:02:20 -07004974 SetRobustLengthParam(length, writeLength);
4975
Geoff Lang0b031062016-10-13 14:30:04 -04004976 return true;
4977}
4978
Geoff Lang0b031062016-10-13 14:30:04 -04004979bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4980 GLuint index,
4981 GLenum pname,
4982 GLsizei bufSize,
4983 GLsizei *length,
4984 GLint *params)
4985{
4986 if (!ValidateRobustEntryPoint(context, bufSize))
4987 {
4988 return false;
4989 }
4990
Brandon Jonesd1049182018-03-28 10:02:20 -07004991 GLsizei writeLength = 0;
4992
4993 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004994 {
4995 return false;
4996 }
4997
Brandon Jonesd1049182018-03-28 10:02:20 -07004998 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004999 {
5000 return false;
5001 }
5002
Brandon Jonesd1049182018-03-28 10:02:20 -07005003 SetRobustLengthParam(length, writeLength);
5004
Geoff Lang0b031062016-10-13 14:30:04 -04005005 return true;
5006}
5007
Geoff Lang0b031062016-10-13 14:30:04 -04005008bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
5009 GLuint index,
5010 GLenum pname,
5011 GLsizei bufSize,
5012 GLsizei *length,
5013 GLuint *params)
5014{
5015 if (!ValidateRobustEntryPoint(context, bufSize))
5016 {
5017 return false;
5018 }
5019
Brandon Jonesd1049182018-03-28 10:02:20 -07005020 GLsizei writeLength = 0;
5021
5022 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04005023 {
5024 return false;
5025 }
5026
Brandon Jonesd1049182018-03-28 10:02:20 -07005027 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04005028 {
5029 return false;
5030 }
5031
Brandon Jonesd1049182018-03-28 10:02:20 -07005032 SetRobustLengthParam(length, writeLength);
5033
Geoff Lang0b031062016-10-13 14:30:04 -04005034 return true;
5035}
5036
Geoff Lang6899b872016-10-14 11:30:13 -04005037bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5038 GLuint program,
5039 GLuint uniformBlockIndex,
5040 GLenum pname,
5041 GLsizei bufSize,
5042 GLsizei *length,
5043 GLint *params)
5044{
5045 if (!ValidateRobustEntryPoint(context, bufSize))
5046 {
5047 return false;
5048 }
5049
Brandon Jonesd1049182018-03-28 10:02:20 -07005050 GLsizei writeLength = 0;
5051
5052 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5053 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005054 {
5055 return false;
5056 }
5057
Brandon Jonesd1049182018-03-28 10:02:20 -07005058 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005059 {
5060 return false;
5061 }
5062
Brandon Jonesd1049182018-03-28 10:02:20 -07005063 SetRobustLengthParam(length, writeLength);
5064
Geoff Lang6899b872016-10-14 11:30:13 -04005065 return true;
5066}
5067
Brandon Jones416aaf92018-04-10 08:10:16 -07005068bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005069 GLenum target,
5070 GLenum internalformat,
5071 GLenum pname,
5072 GLsizei bufSize,
5073 GLsizei *length,
5074 GLint *params)
5075{
5076 if (!ValidateRobustEntryPoint(context, bufSize))
5077 {
5078 return false;
5079 }
5080
Brandon Jonesd1049182018-03-28 10:02:20 -07005081 GLsizei numParams = 0;
5082
5083 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5084 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005085 {
5086 return false;
5087 }
5088
Brandon Jonesd1049182018-03-28 10:02:20 -07005089 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005090 {
5091 return false;
5092 }
5093
Brandon Jonesd1049182018-03-28 10:02:20 -07005094 SetRobustLengthParam(length, numParams);
5095
Geoff Lang0a9661f2016-10-20 10:59:20 -07005096 return true;
5097}
5098
Jamie Madill5b772312018-03-08 20:28:32 -05005099bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005100 GLuint attribIndex,
5101 GLint size,
5102 GLenum type,
5103 GLboolean pureInteger)
5104{
5105 const Caps &caps = context->getCaps();
5106 if (attribIndex >= caps.maxVertexAttributes)
5107 {
Jamie Madill610640f2018-11-21 17:28:41 -05005108 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005109 return false;
5110 }
5111
5112 if (size < 1 || size > 4)
5113 {
Jamie Madill610640f2018-11-21 17:28:41 -05005114 context->validationError(GL_INVALID_VALUE, kErrorInvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005115 return false;
Shao80957d92017-02-20 21:25:59 +08005116 }
5117
5118 switch (type)
5119 {
5120 case GL_BYTE:
5121 case GL_UNSIGNED_BYTE:
5122 case GL_SHORT:
5123 case GL_UNSIGNED_SHORT:
5124 break;
5125
5126 case GL_INT:
5127 case GL_UNSIGNED_INT:
5128 if (context->getClientMajorVersion() < 3)
5129 {
Jamie Madill610640f2018-11-21 17:28:41 -05005130 context->validationError(GL_INVALID_ENUM,
5131 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005132 return false;
5133 }
5134 break;
5135
5136 case GL_FIXED:
5137 case GL_FLOAT:
5138 if (pureInteger)
5139 {
Jamie Madill610640f2018-11-21 17:28:41 -05005140 context->validationError(GL_INVALID_ENUM, kErrorInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005141 return false;
5142 }
5143 break;
5144
5145 case GL_HALF_FLOAT:
5146 if (context->getClientMajorVersion() < 3)
5147 {
Jamie Madill610640f2018-11-21 17:28:41 -05005148 context->validationError(GL_INVALID_ENUM,
5149 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005150 return false;
5151 }
5152 if (pureInteger)
5153 {
Jamie Madill610640f2018-11-21 17:28:41 -05005154 context->validationError(GL_INVALID_ENUM, kErrorInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005155 return false;
5156 }
5157 break;
5158
5159 case GL_INT_2_10_10_10_REV:
5160 case GL_UNSIGNED_INT_2_10_10_10_REV:
5161 if (context->getClientMajorVersion() < 3)
5162 {
Jamie Madill610640f2018-11-21 17:28:41 -05005163 context->validationError(GL_INVALID_ENUM,
5164 "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005165 return false;
5166 }
5167 if (pureInteger)
5168 {
Jamie Madill610640f2018-11-21 17:28:41 -05005169 context->validationError(GL_INVALID_ENUM, kErrorInvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005170 return false;
5171 }
5172 if (size != 4)
5173 {
Jamie Madill610640f2018-11-21 17:28:41 -05005174 context->validationError(GL_INVALID_OPERATION,
5175 "Type is INT_2_10_10_10_REV or "
5176 "UNSIGNED_INT_2_10_10_10_REV and "
5177 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005178 return false;
5179 }
5180 break;
5181
5182 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005183 context->validationError(GL_INVALID_ENUM, kErrorInvalidType);
Shao80957d92017-02-20 21:25:59 +08005184 return false;
5185 }
5186
5187 return true;
5188}
5189
Geoff Lang76e65652017-03-27 14:58:02 -04005190// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5191// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5192// specified clear value and the type of a buffer that is being cleared generates an
5193// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005194bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005195 GLint drawbuffer,
5196 const GLenum *validComponentTypes,
5197 size_t validComponentTypeCount)
5198{
5199 const FramebufferAttachment *attachment =
5200 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5201 if (attachment)
5202 {
5203 GLenum componentType = attachment->getFormat().info->componentType;
5204 const GLenum *end = validComponentTypes + validComponentTypeCount;
5205 if (std::find(validComponentTypes, end, componentType) == end)
5206 {
Jamie Madill610640f2018-11-21 17:28:41 -05005207 context->validationError(
5208 GL_INVALID_OPERATION,
5209 "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005210 return false;
5211 }
5212 }
5213
5214 return true;
5215}
5216
Jamie Madill5b772312018-03-08 20:28:32 -05005217bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005218{
5219 if (!ValidateRobustEntryPoint(context, dataSize))
5220 {
5221 return false;
5222 }
5223
Jamie Madill43da7c42018-08-01 11:34:49 -04005224 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005225 if (pixelUnpackBuffer == nullptr)
5226 {
5227 if (dataSize < imageSize)
5228 {
Jamie Madill610640f2018-11-21 17:28:41 -05005229 context->validationError(GL_INVALID_OPERATION, "dataSize is too small");
Corentin Wallezb2931602017-04-11 15:58:57 -04005230 }
5231 }
5232 return true;
5233}
5234
Jamie Madill5b772312018-03-08 20:28:32 -05005235bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005236 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005237 GLenum pname,
5238 bool pointerVersion,
5239 GLsizei *numParams)
5240{
5241 if (numParams)
5242 {
5243 *numParams = 0;
5244 }
5245
Corentin Walleze4477002017-12-01 14:39:58 -05005246 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005247 {
Jamie Madill610640f2018-11-21 17:28:41 -05005248 context->validationError(GL_INVALID_ENUM, kErrorInvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005249 return false;
5250 }
5251
5252 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5253 if (!buffer)
5254 {
5255 // A null buffer means that "0" is bound to the requested buffer target
Jamie Madill610640f2018-11-21 17:28:41 -05005256 context->validationError(GL_INVALID_OPERATION, kErrorBufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005257 return false;
5258 }
5259
5260 const Extensions &extensions = context->getExtensions();
5261
5262 switch (pname)
5263 {
5264 case GL_BUFFER_USAGE:
5265 case GL_BUFFER_SIZE:
5266 break;
5267
5268 case GL_BUFFER_ACCESS_OES:
5269 if (!extensions.mapBuffer)
5270 {
Jamie Madill610640f2018-11-21 17:28:41 -05005271 context->validationError(GL_INVALID_ENUM,
5272 "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005273 return false;
5274 }
5275 break;
5276
5277 case GL_BUFFER_MAPPED:
5278 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5279 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5280 !extensions.mapBufferRange)
5281 {
Jamie Madill610640f2018-11-21 17:28:41 -05005282 context->validationError(GL_INVALID_ENUM,
5283 "pname requires OpenGL ES 3.0, "
5284 "GL_OES_mapbuffer or "
5285 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005286 return false;
5287 }
5288 break;
5289
5290 case GL_BUFFER_MAP_POINTER:
5291 if (!pointerVersion)
5292 {
Jamie Madill610640f2018-11-21 17:28:41 -05005293 context->validationError(
5294 GL_INVALID_ENUM,
5295 "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005296 return false;
5297 }
5298 break;
5299
5300 case GL_BUFFER_ACCESS_FLAGS:
5301 case GL_BUFFER_MAP_OFFSET:
5302 case GL_BUFFER_MAP_LENGTH:
5303 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5304 {
Jamie Madill610640f2018-11-21 17:28:41 -05005305 context->validationError(
5306 GL_INVALID_ENUM, "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005307 return false;
5308 }
5309 break;
5310
Geoff Lang79b91402018-10-04 15:11:30 -04005311 case GL_MEMORY_SIZE_ANGLE:
5312 if (!context->getExtensions().memorySize)
5313 {
Jamie Madill610640f2018-11-21 17:28:41 -05005314 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005315 return false;
5316 }
5317 break;
5318
Jamie Madillbe849e42017-05-02 15:49:00 -04005319 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005320 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005321 return false;
5322 }
5323
5324 // All buffer parameter queries return one value.
5325 if (numParams)
5326 {
5327 *numParams = 1;
5328 }
5329
5330 return true;
5331}
5332
5333bool ValidateGetRenderbufferParameterivBase(Context *context,
5334 GLenum target,
5335 GLenum pname,
5336 GLsizei *length)
5337{
5338 if (length)
5339 {
5340 *length = 0;
5341 }
5342
5343 if (target != GL_RENDERBUFFER)
5344 {
Jamie Madill610640f2018-11-21 17:28:41 -05005345 context->validationError(GL_INVALID_ENUM, kErrorInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005346 return false;
5347 }
5348
5349 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5350 if (renderbuffer == nullptr)
5351 {
Jamie Madill610640f2018-11-21 17:28:41 -05005352 context->validationError(GL_INVALID_OPERATION, kErrorRenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005353 return false;
5354 }
5355
5356 switch (pname)
5357 {
5358 case GL_RENDERBUFFER_WIDTH:
5359 case GL_RENDERBUFFER_HEIGHT:
5360 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5361 case GL_RENDERBUFFER_RED_SIZE:
5362 case GL_RENDERBUFFER_GREEN_SIZE:
5363 case GL_RENDERBUFFER_BLUE_SIZE:
5364 case GL_RENDERBUFFER_ALPHA_SIZE:
5365 case GL_RENDERBUFFER_DEPTH_SIZE:
5366 case GL_RENDERBUFFER_STENCIL_SIZE:
5367 break;
5368
5369 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5370 if (!context->getExtensions().framebufferMultisample)
5371 {
Jamie Madill610640f2018-11-21 17:28:41 -05005372 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005373 return false;
5374 }
5375 break;
5376
Geoff Lang79b91402018-10-04 15:11:30 -04005377 case GL_MEMORY_SIZE_ANGLE:
5378 if (!context->getExtensions().memorySize)
5379 {
Jamie Madill610640f2018-11-21 17:28:41 -05005380 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005381 return false;
5382 }
5383 break;
5384
Jamie Madillbe849e42017-05-02 15:49:00 -04005385 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005386 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005387 return false;
5388 }
5389
5390 if (length)
5391 {
5392 *length = 1;
5393 }
5394 return true;
5395}
5396
5397bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5398{
5399 if (length)
5400 {
5401 *length = 0;
5402 }
5403
5404 if (GetValidShader(context, shader) == nullptr)
5405 {
5406 return false;
5407 }
5408
5409 switch (pname)
5410 {
5411 case GL_SHADER_TYPE:
5412 case GL_DELETE_STATUS:
5413 case GL_COMPILE_STATUS:
5414 case GL_INFO_LOG_LENGTH:
5415 case GL_SHADER_SOURCE_LENGTH:
5416 break;
5417
5418 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5419 if (!context->getExtensions().translatedShaderSource)
5420 {
Jamie Madill610640f2018-11-21 17:28:41 -05005421 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005422 return false;
5423 }
5424 break;
5425
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005426 case GL_COMPLETION_STATUS_KHR:
5427 if (!context->getExtensions().parallelShaderCompile)
5428 {
Jamie Madill610640f2018-11-21 17:28:41 -05005429 context->validationError(GL_INVALID_OPERATION, kErrorExtensionNotEnabled);
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005430 return false;
5431 }
5432 break;
5433
Jamie Madillbe849e42017-05-02 15:49:00 -04005434 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005435 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005436 return false;
5437 }
5438
5439 if (length)
5440 {
5441 *length = 1;
5442 }
5443 return true;
5444}
5445
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005446bool ValidateGetTexParameterBase(Context *context,
5447 TextureType target,
5448 GLenum pname,
5449 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005450{
5451 if (length)
5452 {
5453 *length = 0;
5454 }
5455
5456 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5457 {
Jamie Madill610640f2018-11-21 17:28:41 -05005458 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005459 return false;
5460 }
5461
5462 if (context->getTargetTexture(target) == nullptr)
5463 {
5464 // Should only be possible for external textures
Jamie Madill610640f2018-11-21 17:28:41 -05005465 context->validationError(GL_INVALID_ENUM, kErrorTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005466 return false;
5467 }
5468
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005469 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5470 {
Jamie Madill610640f2018-11-21 17:28:41 -05005471 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005472 return false;
5473 }
5474
Jamie Madillbe849e42017-05-02 15:49:00 -04005475 switch (pname)
5476 {
5477 case GL_TEXTURE_MAG_FILTER:
5478 case GL_TEXTURE_MIN_FILTER:
5479 case GL_TEXTURE_WRAP_S:
5480 case GL_TEXTURE_WRAP_T:
5481 break;
5482
5483 case GL_TEXTURE_USAGE_ANGLE:
5484 if (!context->getExtensions().textureUsage)
5485 {
Jamie Madill610640f2018-11-21 17:28:41 -05005486 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005487 return false;
5488 }
5489 break;
5490
5491 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005492 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005493 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005494 return false;
5495 }
5496 break;
5497
5498 case GL_TEXTURE_IMMUTABLE_FORMAT:
5499 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5500 {
Jamie Madill610640f2018-11-21 17:28:41 -05005501 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005502 return false;
5503 }
5504 break;
5505
5506 case GL_TEXTURE_WRAP_R:
5507 case GL_TEXTURE_IMMUTABLE_LEVELS:
5508 case GL_TEXTURE_SWIZZLE_R:
5509 case GL_TEXTURE_SWIZZLE_G:
5510 case GL_TEXTURE_SWIZZLE_B:
5511 case GL_TEXTURE_SWIZZLE_A:
5512 case GL_TEXTURE_BASE_LEVEL:
5513 case GL_TEXTURE_MAX_LEVEL:
5514 case GL_TEXTURE_MIN_LOD:
5515 case GL_TEXTURE_MAX_LOD:
5516 case GL_TEXTURE_COMPARE_MODE:
5517 case GL_TEXTURE_COMPARE_FUNC:
5518 if (context->getClientMajorVersion() < 3)
5519 {
Jamie Madill610640f2018-11-21 17:28:41 -05005520 context->validationError(GL_INVALID_ENUM, "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005521 return false;
5522 }
5523 break;
5524
5525 case GL_TEXTURE_SRGB_DECODE_EXT:
5526 if (!context->getExtensions().textureSRGBDecode)
5527 {
Jamie Madill610640f2018-11-21 17:28:41 -05005528 context->validationError(GL_INVALID_ENUM,
5529 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005530 return false;
5531 }
5532 break;
5533
Yunchao Hebacaa712018-01-30 14:01:39 +08005534 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5535 if (context->getClientVersion() < Version(3, 1))
5536 {
Jamie Madill610640f2018-11-21 17:28:41 -05005537 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Yunchao Hebacaa712018-01-30 14:01:39 +08005538 return false;
5539 }
5540 break;
5541
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005542 case GL_GENERATE_MIPMAP:
5543 case GL_TEXTURE_CROP_RECT_OES:
5544 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5545 // after GL_OES_draw_texture functionality implemented
5546 if (context->getClientMajorVersion() > 1)
5547 {
Jamie Madill610640f2018-11-21 17:28:41 -05005548 context->validationError(GL_INVALID_ENUM, kErrorGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005549 return false;
5550 }
5551 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005552
5553 case GL_MEMORY_SIZE_ANGLE:
5554 if (!context->getExtensions().memorySize)
5555 {
Jamie Madill610640f2018-11-21 17:28:41 -05005556 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Geoff Lang79b91402018-10-04 15:11:30 -04005557 return false;
5558 }
5559 break;
5560
Till Rathmannb8543632018-10-02 19:46:14 +02005561 case GL_TEXTURE_BORDER_COLOR:
5562 if (!context->getExtensions().textureBorderClamp)
5563 {
Jamie Madill610640f2018-11-21 17:28:41 -05005564 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02005565 return false;
5566 }
5567 break;
5568
Jamie Madillbe849e42017-05-02 15:49:00 -04005569 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005570 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005571 return false;
5572 }
5573
5574 if (length)
5575 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005576 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005577 }
5578 return true;
5579}
5580
5581bool ValidateGetVertexAttribBase(Context *context,
5582 GLuint index,
5583 GLenum pname,
5584 GLsizei *length,
5585 bool pointer,
5586 bool pureIntegerEntryPoint)
5587{
5588 if (length)
5589 {
5590 *length = 0;
5591 }
5592
5593 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5594 {
Jamie Madill610640f2018-11-21 17:28:41 -05005595 context->validationError(GL_INVALID_OPERATION, "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005596 return false;
5597 }
5598
5599 if (index >= context->getCaps().maxVertexAttributes)
5600 {
Jamie Madill610640f2018-11-21 17:28:41 -05005601 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005602 return false;
5603 }
5604
5605 if (pointer)
5606 {
5607 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5608 {
Jamie Madill610640f2018-11-21 17:28:41 -05005609 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005610 return false;
5611 }
5612 }
5613 else
5614 {
5615 switch (pname)
5616 {
5617 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5618 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5619 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5620 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5621 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5622 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5623 case GL_CURRENT_VERTEX_ATTRIB:
5624 break;
5625
5626 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5627 static_assert(
5628 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5629 "ANGLE extension enums not equal to GL enums.");
5630 if (context->getClientMajorVersion() < 3 &&
5631 !context->getExtensions().instancedArrays)
5632 {
Jamie Madill610640f2018-11-21 17:28:41 -05005633 context->validationError(GL_INVALID_ENUM,
5634 "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5635 "requires OpenGL ES 3.0 or "
5636 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005637 return false;
5638 }
5639 break;
5640
5641 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5642 if (context->getClientMajorVersion() < 3)
5643 {
Jamie Madill610640f2018-11-21 17:28:41 -05005644 context->validationError(
5645 GL_INVALID_ENUM, "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005646 return false;
5647 }
5648 break;
5649
5650 case GL_VERTEX_ATTRIB_BINDING:
5651 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5652 if (context->getClientVersion() < ES_3_1)
5653 {
Jamie Madill610640f2018-11-21 17:28:41 -05005654 context->validationError(GL_INVALID_ENUM,
5655 "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005656 return false;
5657 }
5658 break;
5659
5660 default:
Jamie Madill610640f2018-11-21 17:28:41 -05005661 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005662 return false;
5663 }
5664 }
5665
5666 if (length)
5667 {
5668 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5669 {
5670 *length = 4;
5671 }
5672 else
5673 {
5674 *length = 1;
5675 }
5676 }
5677
5678 return true;
5679}
5680
Jamie Madill4928b7c2017-06-20 12:57:39 -04005681bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005682 GLint x,
5683 GLint y,
5684 GLsizei width,
5685 GLsizei height,
5686 GLenum format,
5687 GLenum type,
5688 GLsizei bufSize,
5689 GLsizei *length,
5690 GLsizei *columns,
5691 GLsizei *rows,
5692 void *pixels)
5693{
5694 if (length != nullptr)
5695 {
5696 *length = 0;
5697 }
5698 if (rows != nullptr)
5699 {
5700 *rows = 0;
5701 }
5702 if (columns != nullptr)
5703 {
5704 *columns = 0;
5705 }
5706
5707 if (width < 0 || height < 0)
5708 {
Jamie Madill610640f2018-11-21 17:28:41 -05005709 context->validationError(GL_INVALID_VALUE, kErrorNegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005710 return false;
5711 }
5712
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005713 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005714
Jamie Madill427064d2018-04-13 16:20:34 -04005715 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005716 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005717 return false;
5718 }
5719
Jamie Madille98b1b52018-03-08 09:47:23 -05005720 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005721 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005722 return false;
5723 }
5724
Jamie Madill690c8eb2018-03-12 15:20:03 -04005725 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005726 ASSERT(framebuffer);
5727
5728 if (framebuffer->getReadBufferState() == GL_NONE)
5729 {
Jamie Madill610640f2018-11-21 17:28:41 -05005730 context->validationError(GL_INVALID_OPERATION, kErrorReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005731 return false;
5732 }
5733
5734 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5735 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5736 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5737 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5738 // situation is an application error that would lead to a crash in ANGLE.
5739 if (readBuffer == nullptr)
5740 {
Jamie Madill610640f2018-11-21 17:28:41 -05005741 context->validationError(GL_INVALID_OPERATION, kErrorMissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005742 return false;
5743 }
5744
Martin Radev28031682017-07-28 14:47:56 +03005745 // ANGLE_multiview, Revision 1:
5746 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005747 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5748 // in the current read framebuffer is more than one.
5749 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005750 {
Jamie Madill610640f2018-11-21 17:28:41 -05005751 context->validationError(GL_INVALID_FRAMEBUFFER_OPERATION,
5752 "Attempting to read from a multi-view framebuffer.");
Martin Radev28031682017-07-28 14:47:56 +03005753 return false;
5754 }
5755
Geoff Lang280ba992017-04-18 16:30:58 -04005756 if (context->getExtensions().webglCompatibility)
5757 {
5758 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5759 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5760 // and type before validating the combination of format and type. However, the
5761 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5762 // verifies that GL_INVALID_OPERATION is generated.
5763 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5764 // dEQP/WebGL.
5765 if (!ValidReadPixelsFormatEnum(context, format))
5766 {
Jamie Madill610640f2018-11-21 17:28:41 -05005767 context->validationError(GL_INVALID_ENUM, kErrorInvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005768 return false;
5769 }
5770
5771 if (!ValidReadPixelsTypeEnum(context, type))
5772 {
Jamie Madill610640f2018-11-21 17:28:41 -05005773 context->validationError(GL_INVALID_ENUM, kErrorInvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005774 return false;
5775 }
5776 }
5777
Jamie Madill690c8eb2018-03-12 15:20:03 -04005778 GLenum currentFormat = GL_NONE;
5779 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5780
5781 GLenum currentType = GL_NONE;
5782 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5783
Jamie Madillbe849e42017-05-02 15:49:00 -04005784 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5785
5786 bool validFormatTypeCombination =
5787 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5788
5789 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5790 {
Jamie Madill610640f2018-11-21 17:28:41 -05005791 context->validationError(GL_INVALID_OPERATION, kErrorMismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005792 return false;
5793 }
5794
5795 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005796 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005797 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5798 {
5799 // ...the buffer object's data store is currently mapped.
Jamie Madill610640f2018-11-21 17:28:41 -05005800 context->validationError(GL_INVALID_OPERATION, "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005801 return false;
5802 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005803 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5804 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5805 {
Jamie Madill610640f2018-11-21 17:28:41 -05005806 context->validationError(GL_INVALID_OPERATION,
5807 kErrorPixelPackBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08005808 return false;
5809 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005810
5811 // .. the data would be packed to the buffer object such that the memory writes required
5812 // would exceed the data store size.
5813 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005814 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005815 const auto &pack = context->getGLState().getPackState();
5816
Jamie Madillca2ff382018-07-11 09:01:17 -04005817 GLuint endByte = 0;
5818 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005819 {
Jamie Madill610640f2018-11-21 17:28:41 -05005820 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005821 return false;
5822 }
5823
Jamie Madillbe849e42017-05-02 15:49:00 -04005824 if (bufSize >= 0)
5825 {
5826 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5827 {
Jamie Madill610640f2018-11-21 17:28:41 -05005828 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005829 return false;
5830 }
5831 }
5832
5833 if (pixelPackBuffer != nullptr)
5834 {
5835 CheckedNumeric<size_t> checkedEndByte(endByte);
5836 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5837 checkedEndByte += checkedOffset;
5838
5839 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5840 {
5841 // Overflow past the end of the buffer
Jamie Madill610640f2018-11-21 17:28:41 -05005842 context->validationError(GL_INVALID_OPERATION, kErrorParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005843 return false;
5844 }
5845 }
5846
5847 if (pixelPackBuffer == nullptr && length != nullptr)
5848 {
5849 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5850 {
Jamie Madill610640f2018-11-21 17:28:41 -05005851 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005852 return false;
5853 }
5854
5855 *length = static_cast<GLsizei>(endByte);
5856 }
5857
Geoff Langa953b522018-02-21 16:56:23 -05005858 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005859 angle::CheckedNumeric<int> clippedExtent(length);
5860 if (start < 0)
5861 {
5862 // "subtract" the area that is less than 0
5863 clippedExtent += start;
5864 }
5865
Geoff Langa953b522018-02-21 16:56:23 -05005866 angle::CheckedNumeric<int> readExtent = start;
5867 readExtent += length;
5868 if (!readExtent.IsValid())
5869 {
5870 return false;
5871 }
5872
5873 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 {
5875 // Subtract the region to the right of the read buffer
5876 clippedExtent -= (readExtent - bufferSize);
5877 }
5878
5879 if (!clippedExtent.IsValid())
5880 {
Geoff Langa953b522018-02-21 16:56:23 -05005881 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005882 }
5883
Geoff Langa953b522018-02-21 16:56:23 -05005884 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5885 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005886 };
5887
Geoff Langa953b522018-02-21 16:56:23 -05005888 GLsizei writtenColumns = 0;
5889 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5890 {
Jamie Madill610640f2018-11-21 17:28:41 -05005891 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005892 return false;
5893 }
5894
5895 GLsizei writtenRows = 0;
5896 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5897 {
Jamie Madill610640f2018-11-21 17:28:41 -05005898 context->validationError(GL_INVALID_OPERATION, kErrorIntegerOverflow);
Geoff Langa953b522018-02-21 16:56:23 -05005899 return false;
5900 }
5901
Jamie Madillbe849e42017-05-02 15:49:00 -04005902 if (columns != nullptr)
5903 {
Geoff Langa953b522018-02-21 16:56:23 -05005904 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005905 }
5906
5907 if (rows != nullptr)
5908 {
Geoff Langa953b522018-02-21 16:56:23 -05005909 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 }
5911
5912 return true;
5913}
5914
5915template <typename ParamType>
5916bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005917 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 GLenum pname,
5919 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005920 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005921 const ParamType *params)
5922{
5923 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5924 {
Jamie Madill610640f2018-11-21 17:28:41 -05005925 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005926 return false;
5927 }
5928
5929 if (context->getTargetTexture(target) == nullptr)
5930 {
5931 // Should only be possible for external textures
Jamie Madill610640f2018-11-21 17:28:41 -05005932 context->validationError(GL_INVALID_ENUM, kErrorTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 return false;
5934 }
5935
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005936 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005937 if (bufSize >= 0 && bufSize < minBufSize)
5938 {
Jamie Madill610640f2018-11-21 17:28:41 -05005939 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005940 return false;
5941 }
5942
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005943 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5944 {
Jamie Madill610640f2018-11-21 17:28:41 -05005945 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005946 return false;
5947 }
5948
Jamie Madillbe849e42017-05-02 15:49:00 -04005949 switch (pname)
5950 {
5951 case GL_TEXTURE_WRAP_R:
5952 case GL_TEXTURE_SWIZZLE_R:
5953 case GL_TEXTURE_SWIZZLE_G:
5954 case GL_TEXTURE_SWIZZLE_B:
5955 case GL_TEXTURE_SWIZZLE_A:
5956 case GL_TEXTURE_BASE_LEVEL:
5957 case GL_TEXTURE_MAX_LEVEL:
5958 case GL_TEXTURE_COMPARE_MODE:
5959 case GL_TEXTURE_COMPARE_FUNC:
5960 case GL_TEXTURE_MIN_LOD:
5961 case GL_TEXTURE_MAX_LOD:
5962 if (context->getClientMajorVersion() < 3)
5963 {
Jamie Madill610640f2018-11-21 17:28:41 -05005964 context->validationError(GL_INVALID_ENUM, kErrorES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 return false;
5966 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005967 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005968 {
Jamie Madill610640f2018-11-21 17:28:41 -05005969 context->validationError(GL_INVALID_ENUM,
5970 "ES3 texture parameters are not "
5971 "available without "
5972 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005973 return false;
5974 }
5975 break;
5976
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005977 case GL_GENERATE_MIPMAP:
5978 case GL_TEXTURE_CROP_RECT_OES:
5979 if (context->getClientMajorVersion() > 1)
5980 {
Jamie Madill610640f2018-11-21 17:28:41 -05005981 context->validationError(GL_INVALID_ENUM, kErrorGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005982 return false;
5983 }
5984 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 default:
5986 break;
5987 }
5988
Olli Etuahod310a432018-08-24 15:40:23 +03005989 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005990 {
5991 switch (pname)
5992 {
5993 case GL_TEXTURE_MIN_FILTER:
5994 case GL_TEXTURE_MAG_FILTER:
5995 case GL_TEXTURE_WRAP_S:
5996 case GL_TEXTURE_WRAP_T:
5997 case GL_TEXTURE_WRAP_R:
5998 case GL_TEXTURE_MIN_LOD:
5999 case GL_TEXTURE_MAX_LOD:
6000 case GL_TEXTURE_COMPARE_MODE:
6001 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02006002 case GL_TEXTURE_BORDER_COLOR:
Jamie Madill610640f2018-11-21 17:28:41 -05006003 context->validationError(GL_INVALID_ENUM,
6004 "Invalid parameter for 2D multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08006005 return false;
6006 }
6007 }
6008
Jamie Madillbe849e42017-05-02 15:49:00 -04006009 switch (pname)
6010 {
6011 case GL_TEXTURE_WRAP_S:
6012 case GL_TEXTURE_WRAP_T:
6013 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006014 {
6015 bool restrictedWrapModes =
6016 target == TextureType::External || target == TextureType::Rectangle;
6017 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006019 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006020 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006021 }
6022 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006023
6024 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006025 {
6026 bool restrictedMinFilter =
6027 target == TextureType::External || target == TextureType::Rectangle;
6028 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04006029 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006030 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006031 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006032 }
6033 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006034
6035 case GL_TEXTURE_MAG_FILTER:
6036 if (!ValidateTextureMagFilterValue(context, params))
6037 {
6038 return false;
6039 }
6040 break;
6041
6042 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04006043 if (!context->getExtensions().textureUsage)
6044 {
Jamie Madill610640f2018-11-21 17:28:41 -05006045 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Geoff Lang91ab54b2017-10-30 15:12:42 -04006046 return false;
6047 }
6048
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 switch (ConvertToGLenum(params[0]))
6050 {
6051 case GL_NONE:
6052 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
6053 break;
6054
6055 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006056 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 return false;
6058 }
6059 break;
6060
6061 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006062 {
6063 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6064 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04006065 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006066 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006067 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006068 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
6069 }
6070 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006071
6072 case GL_TEXTURE_MIN_LOD:
6073 case GL_TEXTURE_MAX_LOD:
6074 // any value is permissible
6075 break;
6076
6077 case GL_TEXTURE_COMPARE_MODE:
6078 if (!ValidateTextureCompareModeValue(context, params))
6079 {
6080 return false;
6081 }
6082 break;
6083
6084 case GL_TEXTURE_COMPARE_FUNC:
6085 if (!ValidateTextureCompareFuncValue(context, params))
6086 {
6087 return false;
6088 }
6089 break;
6090
6091 case GL_TEXTURE_SWIZZLE_R:
6092 case GL_TEXTURE_SWIZZLE_G:
6093 case GL_TEXTURE_SWIZZLE_B:
6094 case GL_TEXTURE_SWIZZLE_A:
6095 switch (ConvertToGLenum(params[0]))
6096 {
6097 case GL_RED:
6098 case GL_GREEN:
6099 case GL_BLUE:
6100 case GL_ALPHA:
6101 case GL_ZERO:
6102 case GL_ONE:
6103 break;
6104
6105 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006106 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006107 return false;
6108 }
6109 break;
6110
6111 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006112 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006113 {
Jamie Madill610640f2018-11-21 17:28:41 -05006114 context->validationError(GL_INVALID_VALUE, "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006115 return false;
6116 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006117 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 {
Jamie Madill610640f2018-11-21 17:28:41 -05006119 context->validationError(GL_INVALID_OPERATION,
6120 "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006121 return false;
6122 }
Olli Etuahod310a432018-08-24 15:40:23 +03006123 if ((target == TextureType::_2DMultisample ||
6124 target == TextureType::_2DMultisampleArray) &&
6125 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006126 {
Jamie Madill610640f2018-11-21 17:28:41 -05006127 context->validationError(GL_INVALID_OPERATION,
6128 "Base level must be 0 for multisampled textures.");
JiangYizhou4cff8d62017-07-06 14:54:09 +08006129 return false;
6130 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006131 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006132 {
Jamie Madill610640f2018-11-21 17:28:41 -05006133 context->validationError(GL_INVALID_OPERATION,
6134 "Base level must be 0 for rectangle textures.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006135 return false;
6136 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006137 break;
6138
6139 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006140 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006141 {
Jamie Madill610640f2018-11-21 17:28:41 -05006142 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006143 return false;
6144 }
6145 break;
6146
6147 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6148 if (context->getClientVersion() < Version(3, 1))
6149 {
Jamie Madill610640f2018-11-21 17:28:41 -05006150 context->validationError(GL_INVALID_ENUM, kErrorEnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006151 return false;
6152 }
6153 switch (ConvertToGLenum(params[0]))
6154 {
6155 case GL_DEPTH_COMPONENT:
6156 case GL_STENCIL_INDEX:
6157 break;
6158
6159 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006160 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006161 return false;
6162 }
6163 break;
6164
6165 case GL_TEXTURE_SRGB_DECODE_EXT:
6166 if (!ValidateTextureSRGBDecodeValue(context, params))
6167 {
6168 return false;
6169 }
6170 break;
6171
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006172 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006173 if (context->getClientMajorVersion() > 1)
6174 {
Jamie Madill610640f2018-11-21 17:28:41 -05006175 context->validationError(GL_INVALID_ENUM, kErrorGLES1Only);
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006176 return false;
6177 }
6178 break;
Till Rathmannb8543632018-10-02 19:46:14 +02006179
6180 case GL_TEXTURE_CROP_RECT_OES:
6181 if (context->getClientMajorVersion() > 1)
6182 {
Jamie Madill610640f2018-11-21 17:28:41 -05006183 context->validationError(GL_INVALID_ENUM, kErrorGLES1Only);
Till Rathmannb8543632018-10-02 19:46:14 +02006184 return false;
6185 }
6186 if (!vectorParams)
6187 {
Jamie Madill610640f2018-11-21 17:28:41 -05006188 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006189 return false;
6190 }
6191 break;
6192
6193 case GL_TEXTURE_BORDER_COLOR:
6194 if (!context->getExtensions().textureBorderClamp)
6195 {
Jamie Madill610640f2018-11-21 17:28:41 -05006196 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006197 return false;
6198 }
6199 if (!vectorParams)
6200 {
Jamie Madill610640f2018-11-21 17:28:41 -05006201 context->validationError(GL_INVALID_ENUM, kErrorInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006202 return false;
6203 }
6204 break;
6205
Jamie Madillbe849e42017-05-02 15:49:00 -04006206 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006207 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006208 return false;
6209 }
6210
6211 return true;
6212}
6213
Till Rathmannb8543632018-10-02 19:46:14 +02006214template bool ValidateTexParameterBase(Context *,
6215 TextureType,
6216 GLenum,
6217 GLsizei,
6218 bool,
6219 const GLfloat *);
6220template bool ValidateTexParameterBase(Context *,
6221 TextureType,
6222 GLenum,
6223 GLsizei,
6224 bool,
6225 const GLint *);
6226template bool ValidateTexParameterBase(Context *,
6227 TextureType,
6228 GLenum,
6229 GLsizei,
6230 bool,
6231 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006232
Jamie Madill5b772312018-03-08 20:28:32 -05006233bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006234{
6235 if (index >= MAX_VERTEX_ATTRIBS)
6236 {
Jamie Madill610640f2018-11-21 17:28:41 -05006237 context->validationError(GL_INVALID_VALUE, kErrorIndexExceedsMaxVertexAttribute);
Jamie Madill12e957f2017-08-26 21:42:26 -04006238 return false;
6239 }
6240
6241 return true;
6242}
6243
6244bool ValidateGetActiveUniformBlockivBase(Context *context,
6245 GLuint program,
6246 GLuint uniformBlockIndex,
6247 GLenum pname,
6248 GLsizei *length)
6249{
6250 if (length)
6251 {
6252 *length = 0;
6253 }
6254
6255 if (context->getClientMajorVersion() < 3)
6256 {
Jamie Madill610640f2018-11-21 17:28:41 -05006257 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill12e957f2017-08-26 21:42:26 -04006258 return false;
6259 }
6260
6261 Program *programObject = GetValidProgram(context, program);
6262 if (!programObject)
6263 {
6264 return false;
6265 }
6266
6267 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6268 {
Jamie Madill610640f2018-11-21 17:28:41 -05006269 context->validationError(GL_INVALID_VALUE,
6270 "uniformBlockIndex exceeds active uniform block count.");
Jamie Madill12e957f2017-08-26 21:42:26 -04006271 return false;
6272 }
6273
6274 switch (pname)
6275 {
6276 case GL_UNIFORM_BLOCK_BINDING:
6277 case GL_UNIFORM_BLOCK_DATA_SIZE:
6278 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6279 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6280 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6281 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6282 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6283 break;
6284
6285 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006286 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madill12e957f2017-08-26 21:42:26 -04006287 return false;
6288 }
6289
6290 if (length)
6291 {
6292 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6293 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006294 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006295 programObject->getUniformBlockByIndex(uniformBlockIndex);
6296 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6297 }
6298 else
6299 {
6300 *length = 1;
6301 }
6302 }
6303
6304 return true;
6305}
6306
Jamie Madill9696d072017-08-26 23:19:57 -04006307template <typename ParamType>
6308bool ValidateSamplerParameterBase(Context *context,
6309 GLuint sampler,
6310 GLenum pname,
6311 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02006312 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04006313 ParamType *params)
6314{
6315 if (context->getClientMajorVersion() < 3)
6316 {
Jamie Madill610640f2018-11-21 17:28:41 -05006317 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006318 return false;
6319 }
6320
6321 if (!context->isSampler(sampler))
6322 {
Jamie Madill610640f2018-11-21 17:28:41 -05006323 context->validationError(GL_INVALID_OPERATION, kErrorInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006324 return false;
6325 }
6326
Till Rathmannb8543632018-10-02 19:46:14 +02006327 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006328 if (bufSize >= 0 && bufSize < minBufSize)
6329 {
Jamie Madill610640f2018-11-21 17:28:41 -05006330 context->validationError(GL_INVALID_OPERATION, kErrorInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006331 return false;
6332 }
6333
6334 switch (pname)
6335 {
6336 case GL_TEXTURE_WRAP_S:
6337 case GL_TEXTURE_WRAP_T:
6338 case GL_TEXTURE_WRAP_R:
6339 if (!ValidateTextureWrapModeValue(context, params, false))
6340 {
6341 return false;
6342 }
6343 break;
6344
6345 case GL_TEXTURE_MIN_FILTER:
6346 if (!ValidateTextureMinFilterValue(context, params, false))
6347 {
6348 return false;
6349 }
6350 break;
6351
6352 case GL_TEXTURE_MAG_FILTER:
6353 if (!ValidateTextureMagFilterValue(context, params))
6354 {
6355 return false;
6356 }
6357 break;
6358
6359 case GL_TEXTURE_MIN_LOD:
6360 case GL_TEXTURE_MAX_LOD:
6361 // any value is permissible
6362 break;
6363
6364 case GL_TEXTURE_COMPARE_MODE:
6365 if (!ValidateTextureCompareModeValue(context, params))
6366 {
6367 return false;
6368 }
6369 break;
6370
6371 case GL_TEXTURE_COMPARE_FUNC:
6372 if (!ValidateTextureCompareFuncValue(context, params))
6373 {
6374 return false;
6375 }
6376 break;
6377
6378 case GL_TEXTURE_SRGB_DECODE_EXT:
6379 if (!ValidateTextureSRGBDecodeValue(context, params))
6380 {
6381 return false;
6382 }
6383 break;
6384
Luc Ferron1b1a8642018-01-23 15:12:01 -05006385 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6386 {
6387 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6388 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6389 {
6390 return false;
6391 }
6392 }
6393 break;
6394
Till Rathmannb8543632018-10-02 19:46:14 +02006395 case GL_TEXTURE_BORDER_COLOR:
6396 if (!context->getExtensions().textureBorderClamp)
6397 {
Jamie Madill610640f2018-11-21 17:28:41 -05006398 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006399 return false;
6400 }
6401 if (!vectorParams)
6402 {
Jamie Madill610640f2018-11-21 17:28:41 -05006403 context->validationError(GL_INVALID_ENUM, kErrorInsufficientBufferSize);
Till Rathmannb8543632018-10-02 19:46:14 +02006404 return false;
6405 }
6406 break;
6407
Jamie Madill9696d072017-08-26 23:19:57 -04006408 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006409 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006410 return false;
6411 }
6412
6413 return true;
6414}
6415
Till Rathmannb8543632018-10-02 19:46:14 +02006416template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6417template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6418template bool ValidateSamplerParameterBase(Context *,
6419 GLuint,
6420 GLenum,
6421 GLsizei,
6422 bool,
6423 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006424
6425bool ValidateGetSamplerParameterBase(Context *context,
6426 GLuint sampler,
6427 GLenum pname,
6428 GLsizei *length)
6429{
6430 if (length)
6431 {
6432 *length = 0;
6433 }
6434
6435 if (context->getClientMajorVersion() < 3)
6436 {
Jamie Madill610640f2018-11-21 17:28:41 -05006437 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006438 return false;
6439 }
6440
6441 if (!context->isSampler(sampler))
6442 {
Jamie Madill610640f2018-11-21 17:28:41 -05006443 context->validationError(GL_INVALID_OPERATION, kErrorInvalidSampler);
Jamie Madill9696d072017-08-26 23:19:57 -04006444 return false;
6445 }
6446
6447 switch (pname)
6448 {
6449 case GL_TEXTURE_WRAP_S:
6450 case GL_TEXTURE_WRAP_T:
6451 case GL_TEXTURE_WRAP_R:
6452 case GL_TEXTURE_MIN_FILTER:
6453 case GL_TEXTURE_MAG_FILTER:
6454 case GL_TEXTURE_MIN_LOD:
6455 case GL_TEXTURE_MAX_LOD:
6456 case GL_TEXTURE_COMPARE_MODE:
6457 case GL_TEXTURE_COMPARE_FUNC:
6458 break;
6459
Luc Ferron1b1a8642018-01-23 15:12:01 -05006460 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6461 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6462 {
6463 return false;
6464 }
6465 break;
6466
Jamie Madill9696d072017-08-26 23:19:57 -04006467 case GL_TEXTURE_SRGB_DECODE_EXT:
6468 if (!context->getExtensions().textureSRGBDecode)
6469 {
Jamie Madill610640f2018-11-21 17:28:41 -05006470 context->validationError(GL_INVALID_ENUM,
6471 "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madill9696d072017-08-26 23:19:57 -04006472 return false;
6473 }
6474 break;
6475
Till Rathmannb8543632018-10-02 19:46:14 +02006476 case GL_TEXTURE_BORDER_COLOR:
6477 if (!context->getExtensions().textureBorderClamp)
6478 {
Jamie Madill610640f2018-11-21 17:28:41 -05006479 context->validationError(GL_INVALID_ENUM, kErrorExtensionNotEnabled);
Till Rathmannb8543632018-10-02 19:46:14 +02006480 return false;
6481 }
6482 break;
6483
Jamie Madill9696d072017-08-26 23:19:57 -04006484 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006485 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006486 return false;
6487 }
6488
6489 if (length)
6490 {
Till Rathmannb8543632018-10-02 19:46:14 +02006491 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006492 }
6493 return true;
6494}
6495
6496bool ValidateGetInternalFormativBase(Context *context,
6497 GLenum target,
6498 GLenum internalformat,
6499 GLenum pname,
6500 GLsizei bufSize,
6501 GLsizei *numParams)
6502{
6503 if (numParams)
6504 {
6505 *numParams = 0;
6506 }
6507
6508 if (context->getClientMajorVersion() < 3)
6509 {
Jamie Madill610640f2018-11-21 17:28:41 -05006510 context->validationError(GL_INVALID_OPERATION, kErrorES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006511 return false;
6512 }
6513
6514 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006515 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006516 {
Jamie Madill610640f2018-11-21 17:28:41 -05006517 context->validationError(GL_INVALID_ENUM, "Internal format is not renderable.");
Jamie Madill9696d072017-08-26 23:19:57 -04006518 return false;
6519 }
6520
6521 switch (target)
6522 {
6523 case GL_RENDERBUFFER:
6524 break;
6525
6526 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006527 if (context->getClientVersion() < ES_3_1 &&
6528 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006529 {
Jamie Madill610640f2018-11-21 17:28:41 -05006530 context->validationError(GL_INVALID_ENUM,
6531 kErrorMultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006532 return false;
6533 }
6534 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006535 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6536 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006537 {
Jamie Madill610640f2018-11-21 17:28:41 -05006538 context->validationError(GL_INVALID_ENUM, kErrorMultisampleArrayExtensionRequired);
Olli Etuahod310a432018-08-24 15:40:23 +03006539 return false;
6540 }
6541 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006542 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006543 context->validationError(GL_INVALID_ENUM, kErrorInvalidTarget);
Jamie Madill9696d072017-08-26 23:19:57 -04006544 return false;
6545 }
6546
6547 if (bufSize < 0)
6548 {
Jamie Madill610640f2018-11-21 17:28:41 -05006549 context->validationError(GL_INVALID_VALUE, kErrorInsufficientBufferSize);
Jamie Madill9696d072017-08-26 23:19:57 -04006550 return false;
6551 }
6552
6553 GLsizei maxWriteParams = 0;
6554 switch (pname)
6555 {
6556 case GL_NUM_SAMPLE_COUNTS:
6557 maxWriteParams = 1;
6558 break;
6559
6560 case GL_SAMPLES:
6561 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6562 break;
6563
6564 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006565 context->validationError(GL_INVALID_ENUM, kErrorEnumNotSupported);
Jamie Madill9696d072017-08-26 23:19:57 -04006566 return false;
6567 }
6568
6569 if (numParams)
6570 {
6571 // glGetInternalFormativ will not overflow bufSize
6572 *numParams = std::min(bufSize, maxWriteParams);
6573 }
6574
6575 return true;
6576}
6577
Jamie Madille98b1b52018-03-08 09:47:23 -05006578bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6579{
Jamie Madill427064d2018-04-13 16:20:34 -04006580 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006581 {
Jamie Madill610640f2018-11-21 17:28:41 -05006582 context->validationError(GL_INVALID_OPERATION,
6583 kErrorInvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006584 return false;
6585 }
6586 return true;
6587}
6588
Lingfeng Yang038dd532018-03-29 17:31:52 -07006589bool ValidateMultitextureUnit(Context *context, GLenum texture)
6590{
6591 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6592 {
Jamie Madill610640f2018-11-21 17:28:41 -05006593 context->validationError(GL_INVALID_ENUM, kErrorInvalidMultitextureUnit);
Lingfeng Yang038dd532018-03-29 17:31:52 -07006594 return false;
6595 }
6596 return true;
6597}
6598
Olli Etuahod310a432018-08-24 15:40:23 +03006599bool ValidateTexStorageMultisample(Context *context,
6600 TextureType target,
6601 GLsizei samples,
6602 GLint internalFormat,
6603 GLsizei width,
6604 GLsizei height)
6605{
6606 const Caps &caps = context->getCaps();
6607 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6608 static_cast<GLuint>(height) > caps.max2DTextureSize)
6609 {
Jamie Madill610640f2018-11-21 17:28:41 -05006610 context->validationError(GL_INVALID_VALUE, kErrorTextureWidthOrHeightOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006611 return false;
6612 }
6613
6614 if (samples == 0)
6615 {
Jamie Madill610640f2018-11-21 17:28:41 -05006616 context->validationError(GL_INVALID_VALUE, kErrorSamplesZero);
Olli Etuahod310a432018-08-24 15:40:23 +03006617 return false;
6618 }
6619
6620 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6621 if (!formatCaps.textureAttachment)
6622 {
Jamie Madill610640f2018-11-21 17:28:41 -05006623 context->validationError(GL_INVALID_ENUM, kErrorRenderableInternalFormat);
Olli Etuahod310a432018-08-24 15:40:23 +03006624 return false;
6625 }
6626
6627 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6628 // is one of the unsized base internalformats listed in table 8.11.
6629 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6630 if (formatInfo.internalFormat == GL_NONE)
6631 {
Jamie Madill610640f2018-11-21 17:28:41 -05006632 context->validationError(GL_INVALID_ENUM, kErrorUnsizedInternalFormatUnsupported);
Olli Etuahod310a432018-08-24 15:40:23 +03006633 return false;
6634 }
6635
6636 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6637 {
Jamie Madill610640f2018-11-21 17:28:41 -05006638 context->validationError(GL_INVALID_OPERATION, kErrorSamplesOutOfRange);
Olli Etuahod310a432018-08-24 15:40:23 +03006639 return false;
6640 }
6641
6642 Texture *texture = context->getTargetTexture(target);
6643 if (!texture || texture->id() == 0)
6644 {
Jamie Madill610640f2018-11-21 17:28:41 -05006645 context->validationError(GL_INVALID_OPERATION, kErrorZeroBoundToTarget);
Olli Etuahod310a432018-08-24 15:40:23 +03006646 return false;
6647 }
6648
6649 if (texture->getImmutableFormat())
6650 {
Jamie Madill610640f2018-11-21 17:28:41 -05006651 context->validationError(GL_INVALID_OPERATION, kErrorImmutableTextureBound);
Olli Etuahod310a432018-08-24 15:40:23 +03006652 return false;
6653 }
6654 return true;
6655}
6656
Yizhou Jiang7818a852018-09-06 15:02:04 +08006657bool ValidateTexStorage2DMultisampleBase(Context *context,
6658 TextureType target,
6659 GLsizei samples,
6660 GLint internalFormat,
6661 GLsizei width,
6662 GLsizei height)
6663{
6664 if (target != TextureType::_2DMultisample)
6665 {
Jamie Madill610640f2018-11-21 17:28:41 -05006666 context->validationError(GL_INVALID_ENUM, kErrorInvalidTarget);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006667 return false;
6668 }
6669
6670 if (width < 1 || height < 1)
6671 {
Jamie Madill610640f2018-11-21 17:28:41 -05006672 context->validationError(GL_INVALID_VALUE, kErrorTextureSizeTooSmall);
Yizhou Jiang7818a852018-09-06 15:02:04 +08006673 return false;
6674 }
6675
6676 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6677}
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006678
6679bool ValidateGetTexLevelParameterBase(Context *context,
6680 TextureTarget target,
6681 GLint level,
6682 GLenum pname,
6683 GLsizei *length)
6684{
6685
6686 if (length)
6687 {
6688 *length = 0;
6689 }
6690
6691 TextureType type = TextureTargetToType(target);
6692
6693 if (!ValidTexLevelDestinationTarget(context, type))
6694 {
Jamie Madill610640f2018-11-21 17:28:41 -05006695 context->validationError(GL_INVALID_ENUM, kErrorInvalidTextureTarget);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006696 return false;
6697 }
6698
6699 if (context->getTargetTexture(type) == nullptr)
6700 {
Jamie Madill610640f2018-11-21 17:28:41 -05006701 context->validationError(GL_INVALID_ENUM, "No texture bound.");
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006702 return false;
6703 }
6704
6705 if (!ValidMipLevel(context, type, level))
6706 {
Jamie Madill610640f2018-11-21 17:28:41 -05006707 context->validationError(GL_INVALID_VALUE, kErrorInvalidMipLevel);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006708 return false;
6709 }
6710
6711 switch (pname)
6712 {
6713 case GL_TEXTURE_RED_TYPE:
6714 case GL_TEXTURE_GREEN_TYPE:
6715 case GL_TEXTURE_BLUE_TYPE:
6716 case GL_TEXTURE_ALPHA_TYPE:
6717 case GL_TEXTURE_DEPTH_TYPE:
6718 break;
6719 case GL_TEXTURE_RED_SIZE:
6720 case GL_TEXTURE_GREEN_SIZE:
6721 case GL_TEXTURE_BLUE_SIZE:
6722 case GL_TEXTURE_ALPHA_SIZE:
6723 case GL_TEXTURE_DEPTH_SIZE:
6724 case GL_TEXTURE_STENCIL_SIZE:
6725 case GL_TEXTURE_SHARED_SIZE:
6726 break;
6727 case GL_TEXTURE_INTERNAL_FORMAT:
6728 case GL_TEXTURE_WIDTH:
6729 case GL_TEXTURE_HEIGHT:
6730 case GL_TEXTURE_DEPTH:
6731 break;
6732 case GL_TEXTURE_SAMPLES:
6733 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
6734 break;
6735 case GL_TEXTURE_COMPRESSED:
6736 break;
6737 default:
Jamie Madill610640f2018-11-21 17:28:41 -05006738 context->validationError(GL_INVALID_ENUM, kErrorInvalidPname);
Yizhou Jiangc0b6c632018-09-06 15:02:04 +08006739 return false;
6740 }
6741
6742 if (length)
6743 {
6744 *length = 1;
6745 }
6746 return true;
6747}
Jamie Madillc29968b2016-01-20 11:17:23 -05006748} // namespace gl