blob: 232224078d2a1f4f7ba9374e64e51ce282baa11a [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES.h: Validation functions for generic OpenGL ES entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES.h"
Jamie Madille2e406c2016-06-02 13:04:10 -040010
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Context.h"
Geoff Langa8406172015-07-21 16:53:39 -040012#include "libANGLE/Display.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070013#include "libANGLE/ErrorStrings.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050014#include "libANGLE/Framebuffer.h"
15#include "libANGLE/FramebufferAttachment.h"
Geoff Langa8406172015-07-21 16:53:39 -040016#include "libANGLE/Image.h"
Geoff Lang7dd2e102014-11-10 15:19:26 -050017#include "libANGLE/Program.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040018#include "libANGLE/Query.h"
19#include "libANGLE/Texture.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/TransformFeedback.h"
21#include "libANGLE/VertexArray.h"
James Darpinian30b604d2018-03-12 17:26:57 -070022#include "libANGLE/angletypes.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/formatutils.h"
jchen10a99ed552017-09-22 08:10:32 +080024#include "libANGLE/queryconversions.h"
Lingfeng Yangf97641c2018-06-21 19:22:45 -070025#include "libANGLE/queryutils.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040026#include "libANGLE/validationES2.h"
27#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040028
29#include "common/mathutil.h"
30#include "common/utilities.h"
31
Jamie Madille2e406c2016-06-02 13:04:10 -040032using namespace angle;
33
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034namespace gl
35{
Jamie Madill1ca74672015-07-21 15:14:11 -040036namespace
37{
Luc Ferron9dbaeba2018-02-01 07:26:59 -050038bool CompressedTextureFormatRequiresExactSize(GLenum internalFormat)
39{
40 // List of compressed format that require that the texture size is smaller than or a multiple of
41 // the compressed block size.
42 switch (internalFormat)
43 {
44 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
45 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
46 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
47 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
48 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
49 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
50 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
51 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
52 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
53 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
54 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
55 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
56 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
57 case GL_COMPRESSED_RGBA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
58 case GL_COMPRESSED_SRGB8_ALPHA8_LOSSY_DECODE_ETC2_EAC_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +030059 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
60 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
61 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
62 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Luc Ferron9dbaeba2018-02-01 07:26:59 -050063 return true;
jchen10a99ed552017-09-22 08:10:32 +080064
Luc Ferron9dbaeba2018-02-01 07:26:59 -050065 default:
66 return false;
67 }
68}
69bool CompressedSubTextureFormatRequiresExactSize(GLenum internalFormat)
70{
71 // Compressed sub textures have additional formats that requires exact size.
72 // ES 3.1, Section 8.7, Page 171
73 return CompressedTextureFormatRequiresExactSize(internalFormat) ||
74 IsETC2EACFormat(internalFormat);
75}
Olli Etuaho8d5571a2018-04-23 12:29:31 +030076
77bool DifferenceCanOverflow(GLint a, GLint b)
78{
79 CheckedNumeric<GLint> checkedA(a);
80 checkedA -= b;
81 // Use negation to make sure that the difference can't overflow regardless of the order.
82 checkedA = -checkedA;
83 return !checkedA.IsValid();
84}
85
Jamie Madill16e28fd2018-09-12 11:03:05 -040086bool ValidateDrawAttribsImpl(Context *context, GLint primcount, GLint maxVertex)
Jamie Madill1ca74672015-07-21 15:14:11 -040087{
Jamie Madill51af38b2018-04-15 08:50:56 -040088 // If we're drawing zero vertices, we have enough data.
Jamie Madill2da53562018-08-01 11:34:47 -040089 ASSERT(primcount > 0);
Jamie Madill51af38b2018-04-15 08:50:56 -040090
Jamie Madill88602e62018-08-08 12:49:30 -040091 // An overflow can happen when adding the offset. Check against a special constant.
92 if (context->getStateCache().getNonInstancedVertexElementLimit() ==
93 VertexAttribute::kIntegerOverflow ||
94 context->getStateCache().getInstancedVertexElementLimit() ==
95 VertexAttribute::kIntegerOverflow)
Jamie Madilla2d1d2d2018-08-01 11:34:46 -040096 {
97 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
98 return false;
99 }
100
101 // [OpenGL ES 3.0.2] section 2.9.4 page 40:
102 // We can return INVALID_OPERATION if our buffer does not have enough backing data.
103 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientVertexBufferSize);
104 return false;
Jamie Madill1ca74672015-07-21 15:14:11 -0400105}
106
Jamie Madill16e28fd2018-09-12 11:03:05 -0400107ANGLE_INLINE bool ValidateDrawAttribs(Context *context, GLint primcount, GLint maxVertex)
108{
109 if (maxVertex <= context->getStateCache().getNonInstancedVertexElementLimit() &&
110 (primcount - 1) <= context->getStateCache().getInstancedVertexElementLimit())
111 {
112 return true;
113 }
114 else
115 {
116 return ValidateDrawAttribsImpl(context, primcount, maxVertex);
117 }
118}
119
Jamie Madill5b772312018-03-08 20:28:32 -0500120bool ValidReadPixelsTypeEnum(Context *context, GLenum type)
Geoff Lang280ba992017-04-18 16:30:58 -0400121{
122 switch (type)
123 {
124 // Types referenced in Table 3.4 of the ES 2.0.25 spec
125 case GL_UNSIGNED_BYTE:
126 case GL_UNSIGNED_SHORT_4_4_4_4:
127 case GL_UNSIGNED_SHORT_5_5_5_1:
128 case GL_UNSIGNED_SHORT_5_6_5:
129 return context->getClientVersion() >= ES_2_0;
130
131 // Types referenced in Table 3.2 of the ES 3.0.5 spec (Except depth stencil)
132 case GL_BYTE:
133 case GL_INT:
134 case GL_SHORT:
135 case GL_UNSIGNED_INT:
136 case GL_UNSIGNED_INT_10F_11F_11F_REV:
137 case GL_UNSIGNED_INT_24_8:
138 case GL_UNSIGNED_INT_2_10_10_10_REV:
139 case GL_UNSIGNED_INT_5_9_9_9_REV:
140 case GL_UNSIGNED_SHORT:
141 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
142 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
143 return context->getClientVersion() >= ES_3_0;
144
145 case GL_FLOAT:
Geoff Lang7d4602f2017-09-13 10:45:09 -0400146 return context->getClientVersion() >= ES_3_0 || context->getExtensions().textureFloat ||
147 context->getExtensions().colorBufferHalfFloat;
Geoff Lang280ba992017-04-18 16:30:58 -0400148
149 case GL_HALF_FLOAT:
150 return context->getClientVersion() >= ES_3_0 ||
151 context->getExtensions().textureHalfFloat;
152
153 case GL_HALF_FLOAT_OES:
154 return context->getExtensions().colorBufferHalfFloat;
155
156 default:
157 return false;
158 }
159}
160
Jamie Madill5b772312018-03-08 20:28:32 -0500161bool ValidReadPixelsFormatEnum(Context *context, GLenum format)
Geoff Lang280ba992017-04-18 16:30:58 -0400162{
163 switch (format)
164 {
165 // Formats referenced in Table 3.4 of the ES 2.0.25 spec (Except luminance)
166 case GL_RGBA:
167 case GL_RGB:
168 case GL_ALPHA:
169 return context->getClientVersion() >= ES_2_0;
170
171 // Formats referenced in Table 3.2 of the ES 3.0.5 spec
172 case GL_RG:
173 case GL_RED:
174 case GL_RGBA_INTEGER:
175 case GL_RGB_INTEGER:
176 case GL_RG_INTEGER:
177 case GL_RED_INTEGER:
178 return context->getClientVersion() >= ES_3_0;
179
180 case GL_SRGB_ALPHA_EXT:
181 case GL_SRGB_EXT:
182 return context->getExtensions().sRGB;
183
184 case GL_BGRA_EXT:
185 return context->getExtensions().readFormatBGRA;
186
187 default:
188 return false;
189 }
190}
191
Jamie Madill5b772312018-03-08 20:28:32 -0500192bool ValidReadPixelsFormatType(Context *context,
Geoff Langf607c602016-09-21 11:46:48 -0400193 GLenum framebufferComponentType,
194 GLenum format,
195 GLenum type)
196{
197 switch (framebufferComponentType)
198 {
199 case GL_UNSIGNED_NORMALIZED:
200 // TODO(geofflang): Don't accept BGRA here. Some chrome internals appear to try to use
201 // ReadPixels with BGRA even if the extension is not present
202 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE) ||
203 (context->getExtensions().readFormatBGRA && format == GL_BGRA_EXT &&
204 type == GL_UNSIGNED_BYTE);
205
206 case GL_SIGNED_NORMALIZED:
207 return (format == GL_RGBA && type == GL_UNSIGNED_BYTE);
208
209 case GL_INT:
210 return (format == GL_RGBA_INTEGER && type == GL_INT);
211
212 case GL_UNSIGNED_INT:
213 return (format == GL_RGBA_INTEGER && type == GL_UNSIGNED_INT);
214
215 case GL_FLOAT:
216 return (format == GL_RGBA && type == GL_FLOAT);
217
218 default:
219 UNREACHABLE();
220 return false;
221 }
222}
223
Geoff Langc1984ed2016-10-07 12:41:00 -0400224template <typename ParamType>
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400225bool ValidateTextureWrapModeValue(Context *context, ParamType *params, bool restrictedWrapModes)
Geoff Langc1984ed2016-10-07 12:41:00 -0400226{
227 switch (ConvertToGLenum(params[0]))
228 {
229 case GL_CLAMP_TO_EDGE:
230 break;
231
Till Rathmannb8543632018-10-02 19:46:14 +0200232 case GL_CLAMP_TO_BORDER:
233 if (!context->getExtensions().textureBorderClamp)
234 {
235 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
236 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.
Brandon Jonesafa75152017-07-21 13:11:29 -0700245 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidWrapModeTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400246 return false;
247 }
248 break;
249
250 default:
Brandon Jonesafa75152017-07-21 13:11:29 -0700251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureWrap);
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.
Brandon Jonesafa75152017-07-21 13:11:29 -0700274 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFilterTexture);
Geoff Langc1984ed2016-10-07 12:41:00 -0400275 return false;
276 }
277 break;
278
279 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700280 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam);
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:
Brandon Jones6cad5662017-06-14 13:25:13 -0700297 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureFilterParam);
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:
Brandon Jonesafa75152017-07-21 13:11:29 -0700315 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
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:
Brandon Jonesafa75152017-07-21 13:11:29 -0700339 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700351 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
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:
Brandon Jonesafa75152017-07-21 13:11:29 -0700362 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnknownParameter);
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 {
373 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
374 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 {
391 ANGLE_VALIDATION_ERR(context, InvalidValue(), OutsideOfBounds);
392 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 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700640 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount);
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 {
Brandon Jonesafa75152017-07-21 13:11:29 -0700660 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativePrimcount);
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
Brandon Jonesafa75152017-07-21 13:11:29 -0700691 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoZeroDivisor);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700786 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700796 ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureNotPow2);
Geoff Langce635692013-09-24 13:56:32 -0400797 return false;
798 }
799
800 if (!ValidMipLevel(context, target, level))
801 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700802 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
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 Madillca2ff382018-07-11 09:01:17 -0400923 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
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 Madillca2ff382018-07-11 09:01:17 -0400937 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
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 {
943 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
944 PixelUnpackBufferBoundForTransformFeedback);
945 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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500953 context->handleError(InvalidOperation()
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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500960 context->handleError(InvalidOperation() << "imageSize must be at least " << endByte);
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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001004 context->handleError(InvalidValue()
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001020 ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType);
Geoff Lang2d62ab72017-03-23 16:54:40 -04001021 return false;
1022 }
1023
1024 if ((stride & sizeMask) != 0)
1025 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001026 ANGLE_VALIDATION_ERR(context, InvalidOperation(), StrideMustBeMultipleOfType);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001046 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Dian Xiang769769a2015-09-09 15:20:08 -07001047 }
1048 else
1049 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001050 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001077 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedShaderName);
Dian Xiang769769a2015-09-09 15:20:08 -07001078 }
1079 else
1080 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001081 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidShaderName);
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 {
1094 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
1095 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 {
Geoff Langfa125c92017-10-24 13:01:46 -04001102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
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 {
Geoff Langfa125c92017-10-24 13:01:46 -04001119 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
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:
Geoff Langfa125c92017-10-24 13:01:46 -04001125 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
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:
Brandon Jones6cad5662017-06-14 13:25:13 -07001145 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001151 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRenderbufferWidthHeight);
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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001161 context->handleError(InvalidEnum());
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001171 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferInternalFormat);
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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001177 context->handleError(InvalidValue());
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001184 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
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 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001199 context->handleError(InvalidEnum());
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001208 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
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 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001225 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidRenderbufferTarget);
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:
Olli Etuahof0e3c192018-08-15 13:37:21 +03001252 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitInvalidFilter);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001258 ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitInvalidMask);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001266 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitOnlyNearestForNonColor);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001276 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitFramebufferMissing);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitFeedbackLoop);
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 {
Olli Etuaho9aef81c2018-04-30 14:56:15 +03001306 ANGLE_VALIDATION_ERR(context, InvalidValue(), BlitDimensionsOutOfRange);
1307 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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001352 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1353 BlitTypeMismatchFixedOrFloat);
Jamie Madill6163c752015-12-07 16:32:59 -05001354 return false;
1355 }
1356 }
1357 else if (readFixedPoint != drawFixedPoint)
1358 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001359 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1360 BlitTypeMismatchFixedPoint);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001367 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1368 BlitTypeMismatchUnsignedInteger);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001374 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1375 BlitTypeMismatchSignedInteger);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001382 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1383 BlitMultisampledFormatOrBoundsMismatch);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitSameImageColor);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitIntegerWithLinearFilter);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001410 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitMissingColor);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001430 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1431 BlitDepthOrStencilFormatMismatch);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001437 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
1438 BlitMultisampledBoundsMismatch);
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 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001444 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitSameImageDepthOrStencil);
Geoff Lange4915782017-04-12 15:19:07 -04001445 return false;
1446 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001447 }
He Yunchao66a41a22016-12-15 16:45:05 +08001448 // WebGL 2.0 BlitFramebuffer when blitting from a missing attachment
1449 else if (drawBuffer)
1450 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitMissingDepthOrStencil);
He Yunchao66a41a22016-12-15 16:45:05 +08001452 return false;
1453 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001454 }
1455 }
1456
Martin Radeva3ed4572017-07-27 18:29:37 +03001457 // ANGLE_multiview, Revision 1:
1458 // Calling BlitFramebuffer will result in an INVALID_FRAMEBUFFER_OPERATION error if the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03001459 // multi-view layout of the current draw framebuffer is not NONE, or if the multi-view layout of
1460 // the current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of
1461 // views in the current read framebuffer is more than one.
1462 if (readFramebuffer->readDisallowedByMultiview())
Martin Radeva3ed4572017-07-27 18:29:37 +03001463 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001464 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitFromMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001465 return false;
1466 }
1467 if (drawFramebuffer->getMultiviewLayout() != GL_NONE)
1468 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03001469 ANGLE_VALIDATION_ERR(context, InvalidFramebufferOperation(), BlitToMultiview);
Martin Radeva3ed4572017-07-27 18:29:37 +03001470 return false;
1471 }
1472
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001473 return true;
1474}
1475
Jamie Madill4928b7c2017-06-20 12:57:39 -04001476bool ValidateReadPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001477 GLint x,
1478 GLint y,
1479 GLsizei width,
1480 GLsizei height,
1481 GLenum format,
1482 GLenum type,
1483 GLsizei bufSize,
1484 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001485 GLsizei *columns,
1486 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001487 void *pixels)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001488{
1489 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madillc29968b2016-01-20 11:17:23 -05001490 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001491 return false;
1492 }
1493
Brandon Jonesd1049182018-03-28 10:02:20 -07001494 GLsizei writeLength = 0;
1495 GLsizei writeColumns = 0;
1496 GLsizei writeRows = 0;
1497
1498 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1499 &writeColumns, &writeRows, pixels))
Jamie Madill26e91952014-03-05 15:01:27 -05001500 {
Geoff Langb1196682014-07-23 13:47:29 -04001501 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001502 }
1503
Brandon Jonesd1049182018-03-28 10:02:20 -07001504 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Jamie Madill26e91952014-03-05 15:01:27 -05001505 {
Geoff Langb1196682014-07-23 13:47:29 -04001506 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001507 }
1508
Brandon Jonesd1049182018-03-28 10:02:20 -07001509 SetRobustLengthParam(length, writeLength);
1510 SetRobustLengthParam(columns, writeColumns);
1511 SetRobustLengthParam(rows, writeRows);
1512
Jamie Madillc29968b2016-01-20 11:17:23 -05001513 return true;
1514}
1515
1516bool ValidateReadnPixelsEXT(Context *context,
1517 GLint x,
1518 GLint y,
1519 GLsizei width,
1520 GLsizei height,
1521 GLenum format,
1522 GLenum type,
1523 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001524 void *pixels)
Jamie Madillc29968b2016-01-20 11:17:23 -05001525{
1526 if (bufSize < 0)
1527 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001528 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc29968b2016-01-20 11:17:23 -05001529 return false;
1530 }
1531
Geoff Lang62fce5b2016-09-30 10:46:35 -04001532 return ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, nullptr,
Geoff Lange93daba2017-03-30 13:54:40 -04001533 nullptr, nullptr, pixels);
Geoff Lang62fce5b2016-09-30 10:46:35 -04001534}
Jamie Madill26e91952014-03-05 15:01:27 -05001535
Jamie Madill4928b7c2017-06-20 12:57:39 -04001536bool ValidateReadnPixelsRobustANGLE(Context *context,
Geoff Lang62fce5b2016-09-30 10:46:35 -04001537 GLint x,
1538 GLint y,
1539 GLsizei width,
1540 GLsizei height,
1541 GLenum format,
1542 GLenum type,
1543 GLsizei bufSize,
1544 GLsizei *length,
Geoff Lange93daba2017-03-30 13:54:40 -04001545 GLsizei *columns,
1546 GLsizei *rows,
Jamie Madill876429b2017-04-20 15:46:24 -04001547 void *data)
Geoff Lang62fce5b2016-09-30 10:46:35 -04001548{
Brandon Jonesd1049182018-03-28 10:02:20 -07001549 GLsizei writeLength = 0;
1550 GLsizei writeColumns = 0;
1551 GLsizei writeRows = 0;
1552
Geoff Lang62fce5b2016-09-30 10:46:35 -04001553 if (!ValidateRobustEntryPoint(context, bufSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04001554 {
Jamie Madille2e406c2016-06-02 13:04:10 -04001555 return false;
1556 }
1557
Brandon Jonesd1049182018-03-28 10:02:20 -07001558 if (!ValidateReadPixelsBase(context, x, y, width, height, format, type, bufSize, &writeLength,
1559 &writeColumns, &writeRows, data))
Jamie Madille2e406c2016-06-02 13:04:10 -04001560 {
Jamie Madillc29968b2016-01-20 11:17:23 -05001561 return false;
Jamie Madill26e91952014-03-05 15:01:27 -05001562 }
1563
Brandon Jonesd1049182018-03-28 10:02:20 -07001564 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang62fce5b2016-09-30 10:46:35 -04001565 {
1566 return false;
1567 }
1568
Brandon Jonesd1049182018-03-28 10:02:20 -07001569 SetRobustLengthParam(length, writeLength);
1570 SetRobustLengthParam(columns, writeColumns);
1571 SetRobustLengthParam(rows, writeRows);
1572
Geoff Lang62fce5b2016-09-30 10:46:35 -04001573 return true;
Jamie Madill26e91952014-03-05 15:01:27 -05001574}
1575
Jamie Madill43da7c42018-08-01 11:34:49 -04001576bool ValidateGenQueriesEXT(Context *context, GLsizei n, GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001577{
1578 if (!context->getExtensions().occlusionQueryBoolean &&
1579 !context->getExtensions().disjointTimerQuery)
1580 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001581 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001582 return false;
1583 }
1584
Olli Etuaho41997e72016-03-10 13:38:39 +02001585 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001586}
1587
Jamie Madill43da7c42018-08-01 11:34:49 -04001588bool ValidateDeleteQueriesEXT(Context *context, GLsizei n, const GLuint *ids)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001589{
1590 if (!context->getExtensions().occlusionQueryBoolean &&
1591 !context->getExtensions().disjointTimerQuery)
1592 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001593 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001594 return false;
1595 }
1596
Olli Etuaho41997e72016-03-10 13:38:39 +02001597 return ValidateGenOrDelete(context, n);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001598}
1599
Jamie Madill43da7c42018-08-01 11:34:49 -04001600bool ValidateIsQueryEXT(Context *context, GLuint id)
Jamie Madillf0e04492017-08-26 15:28:42 -04001601{
1602 if (!context->getExtensions().occlusionQueryBoolean &&
1603 !context->getExtensions().disjointTimerQuery)
1604 {
1605 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
1606 return false;
1607 }
1608
1609 return true;
1610}
1611
Jamie Madill43da7c42018-08-01 11:34:49 -04001612bool ValidateBeginQueryBase(Context *context, QueryType target, GLuint id)
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001613{
1614 if (!ValidQueryType(context, target))
1615 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001617 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001618 }
1619
1620 if (id == 0)
1621 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001622 context->handleError(InvalidOperation() << "Query id is 0");
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001624 }
1625
1626 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1627 // of zero, if the active query object name for <target> is non-zero (for the
1628 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1629 // the active query for either target is non-zero), if <id> is the name of an
1630 // existing query object whose type does not match <target>, or if <id> is the
1631 // active query object name for any query type, the error INVALID_OPERATION is
1632 // generated.
1633
1634 // Ensure no other queries are active
1635 // NOTE: If other queries than occlusion are supported, we will need to check
1636 // separately that:
1637 // a) The query ID passed is not the current active query for any target/type
1638 // b) There are no active queries for the requested target (and in the case
1639 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1640 // no query may be active for either if glBeginQuery targets either.
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001641
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001642 if (context->getGLState().isQueryActive(target))
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001643 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001644 context->handleError(InvalidOperation() << "Other query is active");
Geoff Langb1196682014-07-23 13:47:29 -04001645 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001646 }
1647
1648 Query *queryObject = context->getQuery(id, true, target);
1649
1650 // check that name was obtained with glGenQueries
1651 if (!queryObject)
1652 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001653 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Geoff Langb1196682014-07-23 13:47:29 -04001654 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001655 }
1656
1657 // check for type mismatch
1658 if (queryObject->getType() != target)
1659 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001660 context->handleError(InvalidOperation() << "Query type does not match target");
Geoff Langb1196682014-07-23 13:47:29 -04001661 return false;
Jamie Madilldb2f14c2014-05-13 13:56:30 -04001662 }
1663
1664 return true;
1665}
1666
Jamie Madill43da7c42018-08-01 11:34:49 -04001667bool ValidateBeginQueryEXT(Context *context, QueryType target, GLuint id)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001668{
1669 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001670 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001671 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001672 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001673 return false;
1674 }
1675
1676 return ValidateBeginQueryBase(context, target, id);
1677}
1678
Jamie Madill43da7c42018-08-01 11:34:49 -04001679bool ValidateEndQueryBase(Context *context, QueryType target)
Jamie Madill45c785d2014-05-13 14:09:34 -04001680{
1681 if (!ValidQueryType(context, target))
1682 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001683 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001685 }
1686
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001687 const Query *queryObject = context->getGLState().getActiveQuery(target);
Jamie Madill45c785d2014-05-13 14:09:34 -04001688
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001689 if (queryObject == nullptr)
Jamie Madill45c785d2014-05-13 14:09:34 -04001690 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001691 context->handleError(InvalidOperation() << "Query target not active");
Geoff Langb1196682014-07-23 13:47:29 -04001692 return false;
Jamie Madill45c785d2014-05-13 14:09:34 -04001693 }
1694
Jamie Madill45c785d2014-05-13 14:09:34 -04001695 return true;
1696}
1697
Jamie Madill43da7c42018-08-01 11:34:49 -04001698bool ValidateEndQueryEXT(Context *context, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001699{
1700 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001701 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001702 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001703 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001704 return false;
1705 }
1706
1707 return ValidateEndQueryBase(context, target);
1708}
1709
Corentin Wallezad3ae902018-03-09 13:40:42 -05001710bool ValidateQueryCounterEXT(Context *context, GLuint id, QueryType target)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001711{
1712 if (!context->getExtensions().disjointTimerQuery)
1713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001714 context->handleError(InvalidOperation() << "Disjoint timer query not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001715 return false;
1716 }
1717
Corentin Wallezad3ae902018-03-09 13:40:42 -05001718 if (target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001719 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001720 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryTarget);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001721 return false;
1722 }
1723
1724 Query *queryObject = context->getQuery(id, true, target);
1725 if (queryObject == nullptr)
1726 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001727 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001728 return false;
1729 }
1730
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001731 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001732 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001733 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001734 return false;
1735 }
1736
1737 return true;
1738}
1739
Corentin Wallezad3ae902018-03-09 13:40:42 -05001740bool ValidateGetQueryivBase(Context *context, QueryType target, GLenum pname, GLsizei *numParams)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001741{
Geoff Lang2186c382016-10-14 10:54:54 -04001742 if (numParams)
1743 {
1744 *numParams = 0;
1745 }
1746
Corentin Wallezad3ae902018-03-09 13:40:42 -05001747 if (!ValidQueryType(context, target) && target != QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001748 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001749 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidQueryType);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001750 return false;
1751 }
1752
1753 switch (pname)
1754 {
1755 case GL_CURRENT_QUERY_EXT:
Corentin Wallezad3ae902018-03-09 13:40:42 -05001756 if (target == QueryType::Timestamp)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001758 context->handleError(InvalidEnum() << "Cannot use current query for timestamp");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001759 return false;
1760 }
1761 break;
1762 case GL_QUERY_COUNTER_BITS_EXT:
1763 if (!context->getExtensions().disjointTimerQuery ||
Corentin Wallezad3ae902018-03-09 13:40:42 -05001764 (target != QueryType::Timestamp && target != QueryType::TimeElapsed))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001765 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001766 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001767 return false;
1768 }
1769 break;
1770 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07001771 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001772 return false;
1773 }
1774
Geoff Lang2186c382016-10-14 10:54:54 -04001775 if (numParams)
1776 {
1777 // All queries return only one value
1778 *numParams = 1;
1779 }
1780
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001781 return true;
1782}
1783
Corentin Wallezad3ae902018-03-09 13:40:42 -05001784bool ValidateGetQueryivEXT(Context *context, QueryType target, GLenum pname, GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001785{
1786 if (!context->getExtensions().occlusionQueryBoolean &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001787 !context->getExtensions().disjointTimerQuery && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001788 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001789 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001790 return false;
1791 }
1792
Geoff Lang2186c382016-10-14 10:54:54 -04001793 return ValidateGetQueryivBase(context, target, pname, nullptr);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001794}
1795
Geoff Lang2186c382016-10-14 10:54:54 -04001796bool ValidateGetQueryivRobustANGLE(Context *context,
Corentin Wallezad3ae902018-03-09 13:40:42 -05001797 QueryType target,
Geoff Lang2186c382016-10-14 10:54:54 -04001798 GLenum pname,
1799 GLsizei bufSize,
1800 GLsizei *length,
1801 GLint *params)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001802{
Geoff Lang2186c382016-10-14 10:54:54 -04001803 if (!ValidateRobustEntryPoint(context, bufSize))
1804 {
1805 return false;
1806 }
1807
Brandon Jonesd1049182018-03-28 10:02:20 -07001808 GLsizei numParams = 0;
1809
1810 if (!ValidateGetQueryivBase(context, target, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001811 {
1812 return false;
1813 }
1814
Brandon Jonesd1049182018-03-28 10:02:20 -07001815 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001816 {
1817 return false;
1818 }
1819
Brandon Jonesd1049182018-03-28 10:02:20 -07001820 SetRobustLengthParam(length, numParams);
1821
Geoff Lang2186c382016-10-14 10:54:54 -04001822 return true;
1823}
1824
1825bool ValidateGetQueryObjectValueBase(Context *context, GLuint id, GLenum pname, GLsizei *numParams)
1826{
1827 if (numParams)
1828 {
1829 *numParams = 0;
1830 }
1831
Corentin Wallezad3ae902018-03-09 13:40:42 -05001832 Query *queryObject = context->getQuery(id, false, QueryType::InvalidEnum);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001833
1834 if (!queryObject)
1835 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001836 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidQueryId);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001837 return false;
1838 }
1839
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001840 if (context->getGLState().isQueryActive(queryObject))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001841 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001842 ANGLE_VALIDATION_ERR(context, InvalidOperation(), QueryActive);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001843 return false;
1844 }
1845
1846 switch (pname)
1847 {
1848 case GL_QUERY_RESULT_EXT:
1849 case GL_QUERY_RESULT_AVAILABLE_EXT:
1850 break;
1851
1852 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001853 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001854 return false;
1855 }
1856
Geoff Lang2186c382016-10-14 10:54:54 -04001857 if (numParams)
1858 {
1859 *numParams = 1;
1860 }
1861
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001862 return true;
1863}
1864
1865bool ValidateGetQueryObjectivEXT(Context *context, GLuint id, GLenum pname, GLint *params)
1866{
1867 if (!context->getExtensions().disjointTimerQuery)
1868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001869 context->handleError(InvalidOperation() << "Timer query extension not enabled");
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001870 return false;
1871 }
Geoff Lang2186c382016-10-14 10:54:54 -04001872 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1873}
1874
1875bool ValidateGetQueryObjectivRobustANGLE(Context *context,
1876 GLuint id,
1877 GLenum pname,
1878 GLsizei bufSize,
1879 GLsizei *length,
1880 GLint *params)
1881{
1882 if (!context->getExtensions().disjointTimerQuery)
1883 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001884 context->handleError(InvalidOperation() << "Timer query extension not enabled");
Geoff Lang2186c382016-10-14 10:54:54 -04001885 return false;
1886 }
1887
1888 if (!ValidateRobustEntryPoint(context, bufSize))
1889 {
1890 return false;
1891 }
1892
Brandon Jonesd1049182018-03-28 10:02:20 -07001893 GLsizei numParams = 0;
1894
1895 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001896 {
1897 return false;
1898 }
1899
Brandon Jonesd1049182018-03-28 10:02:20 -07001900 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001901 {
1902 return false;
1903 }
1904
Brandon Jonesd1049182018-03-28 10:02:20 -07001905 SetRobustLengthParam(length, numParams);
1906
Geoff Lang2186c382016-10-14 10:54:54 -04001907 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001908}
1909
1910bool ValidateGetQueryObjectuivEXT(Context *context, GLuint id, GLenum pname, GLuint *params)
1911{
1912 if (!context->getExtensions().disjointTimerQuery &&
Geoff Lang2b4ce802016-04-28 13:34:50 -04001913 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001915 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001916 return false;
1917 }
Geoff Lang2186c382016-10-14 10:54:54 -04001918 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1919}
1920
1921bool ValidateGetQueryObjectuivRobustANGLE(Context *context,
1922 GLuint id,
1923 GLenum pname,
1924 GLsizei bufSize,
1925 GLsizei *length,
1926 GLuint *params)
1927{
1928 if (!context->getExtensions().disjointTimerQuery &&
1929 !context->getExtensions().occlusionQueryBoolean && !context->getExtensions().syncQuery)
1930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001931 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001932 return false;
1933 }
1934
1935 if (!ValidateRobustEntryPoint(context, bufSize))
1936 {
1937 return false;
1938 }
1939
Brandon Jonesd1049182018-03-28 10:02:20 -07001940 GLsizei numParams = 0;
1941
1942 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001943 {
1944 return false;
1945 }
1946
Brandon Jonesd1049182018-03-28 10:02:20 -07001947 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001948 {
1949 return false;
1950 }
1951
Brandon Jonesd1049182018-03-28 10:02:20 -07001952 SetRobustLengthParam(length, numParams);
1953
Geoff Lang2186c382016-10-14 10:54:54 -04001954 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001955}
1956
1957bool ValidateGetQueryObjecti64vEXT(Context *context, GLuint id, GLenum pname, GLint64 *params)
1958{
1959 if (!context->getExtensions().disjointTimerQuery)
1960 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001961 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001962 return false;
1963 }
Geoff Lang2186c382016-10-14 10:54:54 -04001964 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
1965}
1966
1967bool ValidateGetQueryObjecti64vRobustANGLE(Context *context,
1968 GLuint id,
1969 GLenum pname,
1970 GLsizei bufSize,
1971 GLsizei *length,
1972 GLint64 *params)
1973{
1974 if (!context->getExtensions().disjointTimerQuery)
1975 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001976 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04001977 return false;
1978 }
1979
1980 if (!ValidateRobustEntryPoint(context, bufSize))
1981 {
1982 return false;
1983 }
1984
Brandon Jonesd1049182018-03-28 10:02:20 -07001985 GLsizei numParams = 0;
1986
1987 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001988 {
1989 return false;
1990 }
1991
Brandon Jonesd1049182018-03-28 10:02:20 -07001992 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04001993 {
1994 return false;
1995 }
1996
Brandon Jonesd1049182018-03-28 10:02:20 -07001997 SetRobustLengthParam(length, numParams);
1998
Geoff Lang2186c382016-10-14 10:54:54 -04001999 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002000}
2001
2002bool ValidateGetQueryObjectui64vEXT(Context *context, GLuint id, GLenum pname, GLuint64 *params)
2003{
2004 if (!context->getExtensions().disjointTimerQuery)
2005 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002006 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002007 return false;
2008 }
Geoff Lang2186c382016-10-14 10:54:54 -04002009 return ValidateGetQueryObjectValueBase(context, id, pname, nullptr);
2010}
2011
2012bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
2013 GLuint id,
2014 GLenum pname,
2015 GLsizei bufSize,
2016 GLsizei *length,
2017 GLuint64 *params)
2018{
2019 if (!context->getExtensions().disjointTimerQuery)
2020 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lang2186c382016-10-14 10:54:54 -04002022 return false;
2023 }
2024
2025 if (!ValidateRobustEntryPoint(context, bufSize))
2026 {
2027 return false;
2028 }
2029
Brandon Jonesd1049182018-03-28 10:02:20 -07002030 GLsizei numParams = 0;
2031
2032 if (!ValidateGetQueryObjectValueBase(context, id, pname, &numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002033 {
2034 return false;
2035 }
2036
Brandon Jonesd1049182018-03-28 10:02:20 -07002037 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang2186c382016-10-14 10:54:54 -04002038 {
2039 return false;
2040 }
2041
Brandon Jonesd1049182018-03-28 10:02:20 -07002042 SetRobustLengthParam(length, numParams);
2043
Geoff Lang2186c382016-10-14 10:54:54 -04002044 return true;
Ian Ewell3ffd78b2016-01-22 16:09:42 -05002045}
2046
Jamie Madill5b772312018-03-08 20:28:32 -05002047bool ValidateUniformCommonBase(Context *context,
Jamie Madill43da7c42018-08-01 11:34:49 -04002048 Program *program,
Frank Henigmana98a6472017-02-02 21:38:32 -05002049 GLint location,
2050 GLsizei count,
Jiajia Qin5451d532017-11-16 17:16:34 +08002051 const LinkedUniform **uniformOut)
Frank Henigmana98a6472017-02-02 21:38:32 -05002052{
Jiajia Qin5451d532017-11-16 17:16:34 +08002053 // TODO(Jiajia): Add image uniform check in future.
2054 if (count < 0)
Frank Henigmana98a6472017-02-02 21:38:32 -05002055 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002056 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Frank Henigmana98a6472017-02-02 21:38:32 -05002057 return false;
2058 }
2059
Jiajia Qin5451d532017-11-16 17:16:34 +08002060 if (!program)
2061 {
2062 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidProgramName);
2063 return false;
2064 }
2065
2066 if (!program->isLinked())
2067 {
2068 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
2069 return false;
2070 }
2071
2072 if (location == -1)
2073 {
2074 // Silently ignore the uniform command
2075 return false;
2076 }
2077
2078 const auto &uniformLocations = program->getUniformLocations();
2079 size_t castedLocation = static_cast<size_t>(location);
2080 if (castedLocation >= uniformLocations.size())
2081 {
2082 context->handleError(InvalidOperation() << "Invalid uniform location");
2083 return false;
2084 }
2085
2086 const auto &uniformLocation = uniformLocations[castedLocation];
2087 if (uniformLocation.ignored)
2088 {
2089 // Silently ignore the uniform command
2090 return false;
2091 }
2092
2093 if (!uniformLocation.used())
2094 {
2095 context->handleError(InvalidOperation());
2096 return false;
2097 }
2098
2099 const auto &uniform = program->getUniformByIndex(uniformLocation.index);
2100
2101 // attempting to write an array to a non-array uniform is an INVALID_OPERATION
Jamie Madill2fc08062018-05-10 15:10:55 -04002102 if (count > 1 && !uniform.isArray())
Jiajia Qin5451d532017-11-16 17:16:34 +08002103 {
2104 context->handleError(InvalidOperation());
2105 return false;
2106 }
2107
2108 *uniformOut = &uniform;
2109 return true;
Frank Henigmana98a6472017-02-02 21:38:32 -05002110}
2111
Jamie Madill5b772312018-03-08 20:28:32 -05002112bool ValidateUniform1ivValue(Context *context,
Jiajia Qin5451d532017-11-16 17:16:34 +08002113 GLenum uniformType,
2114 GLsizei count,
2115 const GLint *value)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002116{
Jiajia Qin5451d532017-11-16 17:16:34 +08002117 // Value type is GL_INT, because we only get here from glUniform1i{v}.
2118 // It is compatible with INT or BOOL.
2119 // Do these cheap tests first, for a little extra speed.
2120 if (GL_INT == uniformType || GL_BOOL == uniformType)
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002121 {
Jiajia Qin5451d532017-11-16 17:16:34 +08002122 return true;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002123 }
2124
Jiajia Qin5451d532017-11-16 17:16:34 +08002125 if (IsSamplerType(uniformType))
2126 {
2127 // Check that the values are in range.
2128 const GLint max = context->getCaps().maxCombinedTextureImageUnits;
2129 for (GLsizei i = 0; i < count; ++i)
2130 {
2131 if (value[i] < 0 || value[i] >= max)
2132 {
2133 context->handleError(InvalidValue() << "sampler uniform value out of range");
2134 return false;
2135 }
2136 }
2137 return true;
2138 }
2139
2140 context->handleError(InvalidOperation() << "wrong type of value for uniform");
2141 return false;
2142}
2143
Jamie Madill5b772312018-03-08 20:28:32 -05002144bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum uniformType)
Jiajia Qin5451d532017-11-16 17:16:34 +08002145{
2146 // Check that the value type is compatible with uniform type.
2147 if (valueType == uniformType)
2148 {
2149 return true;
2150 }
2151
2152 context->handleError(InvalidOperation() << "wrong type of value for uniform");
2153 return false;
Jiajia Qinee9f08c2016-11-16 10:06:10 +08002154}
2155
Jamie Madill5b772312018-03-08 20:28:32 -05002156bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002157{
Jamie Madill62d31cb2015-09-11 13:25:51 -04002158 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002159 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002160 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2161 ValidateUniformValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002162}
2163
Jamie Madill5b772312018-03-08 20:28:32 -05002164bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
Frank Henigmana98a6472017-02-02 21:38:32 -05002165{
2166 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002167 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmana98a6472017-02-02 21:38:32 -05002168 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2169 ValidateUniform1ivValue(context, uniform->type, count, value);
2170}
2171
Jamie Madill5b772312018-03-08 20:28:32 -05002172bool ValidateUniformMatrix(Context *context,
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002173 GLenum valueType,
He Yunchaoced53ae2016-11-29 15:00:51 +08002174 GLint location,
2175 GLsizei count,
Jamie Madillaa981bd2014-05-20 10:55:55 -04002176 GLboolean transpose)
2177{
Geoff Lang92019432017-11-20 13:09:34 -05002178 if (ConvertToBool(transpose) && context->getClientMajorVersion() < 3)
Jamie Madillaa981bd2014-05-20 10:55:55 -04002179 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002180 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002181 return false;
Jamie Madillaa981bd2014-05-20 10:55:55 -04002182 }
2183
Jamie Madill62d31cb2015-09-11 13:25:51 -04002184 const LinkedUniform *uniform = nullptr;
Jamie Madill785e8a02018-10-04 17:42:00 -04002185 Program *programObject = context->getGLState().getLinkedProgram(context);
Frank Henigmanf5f74ae2017-02-02 21:14:23 -05002186 return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
2187 ValidateUniformMatrixValue(context, valueType, uniform->type);
Jamie Madillaa981bd2014-05-20 10:55:55 -04002188}
2189
Jamie Madill5b772312018-03-08 20:28:32 -05002190bool ValidateStateQuery(Context *context, GLenum pname, GLenum *nativeType, unsigned int *numParams)
Jamie Madill893ab082014-05-16 16:56:10 -04002191{
2192 if (!context->getQueryParameterInfo(pname, nativeType, numParams))
2193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002194 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04002195 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002196 }
2197
Jamie Madill0af26e12015-03-05 19:54:33 -05002198 const Caps &caps = context->getCaps();
2199
Jamie Madill893ab082014-05-16 16:56:10 -04002200 if (pname >= GL_DRAW_BUFFER0 && pname <= GL_DRAW_BUFFER15)
2201 {
2202 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0);
2203
Jamie Madill0af26e12015-03-05 19:54:33 -05002204 if (colorAttachment >= caps.maxDrawBuffers)
Jamie Madill893ab082014-05-16 16:56:10 -04002205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002207 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002208 }
2209 }
2210
2211 switch (pname)
2212 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002213 case GL_TEXTURE_BINDING_2D:
2214 case GL_TEXTURE_BINDING_CUBE_MAP:
2215 case GL_TEXTURE_BINDING_3D:
2216 case GL_TEXTURE_BINDING_2D_ARRAY:
JiangYizhou24fe74c2017-07-06 16:56:50 +08002217 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08002218 break;
Olli Etuahod310a432018-08-24 15:40:23 +03002219 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
Olli Etuaho064458a2018-08-30 14:02:02 +03002220 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03002221 {
2222 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
2223 return false;
2224 }
2225 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002226 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2227 if (!context->getExtensions().textureRectangle)
2228 {
2229 context->handleError(InvalidEnum()
2230 << "ANGLE_texture_rectangle extension not present");
2231 return false;
2232 }
2233 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002234 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2235 if (!context->getExtensions().eglStreamConsumerExternal &&
2236 !context->getExtensions().eglImageExternal)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidEnum() << "Neither NV_EGL_stream_consumer_external "
2239 "nor GL_OES_EGL_image_external "
2240 "extensions enabled");
He Yunchaoced53ae2016-11-29 15:00:51 +08002241 return false;
2242 }
2243 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002244
He Yunchaoced53ae2016-11-29 15:00:51 +08002245 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2246 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
Jamie Madill893ab082014-05-16 16:56:10 -04002247 {
Jamie Madille98b1b52018-03-08 09:47:23 -05002248 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2249 ASSERT(readFramebuffer);
2250
Jamie Madill427064d2018-04-13 16:20:34 -04002251 if (!ValidateFramebufferComplete<InvalidOperation>(context, readFramebuffer))
Jamie Madill893ab082014-05-16 16:56:10 -04002252 {
Geoff Langb1196682014-07-23 13:47:29 -04002253 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002254 }
2255
Jamie Madille98b1b52018-03-08 09:47:23 -05002256 if (readFramebuffer->getReadBufferState() == GL_NONE)
Martin Radev138064f2016-07-15 12:03:41 +03002257 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002258 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002259 return false;
2260 }
2261
Jamie Madille98b1b52018-03-08 09:47:23 -05002262 const FramebufferAttachment *attachment = readFramebuffer->getReadColorbuffer();
Jamie Madill3c7fa222014-06-05 13:08:51 -04002263 if (!attachment)
Jamie Madill893ab082014-05-16 16:56:10 -04002264 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002265 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002266 return false;
Jamie Madill893ab082014-05-16 16:56:10 -04002267 }
2268 }
2269 break;
2270
He Yunchaoced53ae2016-11-29 15:00:51 +08002271 default:
2272 break;
Jamie Madill893ab082014-05-16 16:56:10 -04002273 }
2274
2275 // pname is valid, but there are no parameters to return
Geoff Langff5b2d52016-09-07 11:32:23 -04002276 if (*numParams == 0)
2277 {
2278 return false;
2279 }
2280
2281 return true;
2282}
2283
Brandon Jonesd1049182018-03-28 10:02:20 -07002284bool ValidateGetBooleanvRobustANGLE(Context *context,
2285 GLenum pname,
2286 GLsizei bufSize,
2287 GLsizei *length,
2288 GLboolean *params)
2289{
2290 GLenum nativeType;
2291 unsigned int numParams = 0;
2292
2293 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2294 {
2295 return false;
2296 }
2297
2298 SetRobustLengthParam(length, numParams);
2299
2300 return true;
2301}
2302
2303bool ValidateGetFloatvRobustANGLE(Context *context,
2304 GLenum pname,
2305 GLsizei bufSize,
2306 GLsizei *length,
2307 GLfloat *params)
2308{
2309 GLenum nativeType;
2310 unsigned int numParams = 0;
2311
2312 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2313 {
2314 return false;
2315 }
2316
2317 SetRobustLengthParam(length, numParams);
2318
2319 return true;
2320}
2321
2322bool ValidateGetIntegervRobustANGLE(Context *context,
2323 GLenum pname,
2324 GLsizei bufSize,
2325 GLsizei *length,
2326 GLint *data)
2327{
2328 GLenum nativeType;
2329 unsigned int numParams = 0;
2330
2331 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2332 {
2333 return false;
2334 }
2335
2336 SetRobustLengthParam(length, numParams);
2337
2338 return true;
2339}
2340
2341bool ValidateGetInteger64vRobustANGLE(Context *context,
2342 GLenum pname,
2343 GLsizei bufSize,
2344 GLsizei *length,
2345 GLint64 *data)
2346{
2347 GLenum nativeType;
2348 unsigned int numParams = 0;
2349
2350 if (!ValidateRobustStateQuery(context, pname, bufSize, &nativeType, &numParams))
2351 {
2352 return false;
2353 }
2354
2355 if (nativeType == GL_INT_64_ANGLEX)
2356 {
2357 CastStateValues(context, nativeType, pname, numParams, data);
2358 return false;
2359 }
2360
2361 SetRobustLengthParam(length, numParams);
2362 return true;
2363}
2364
Jamie Madill5b772312018-03-08 20:28:32 -05002365bool ValidateRobustStateQuery(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04002366 GLenum pname,
2367 GLsizei bufSize,
2368 GLenum *nativeType,
2369 unsigned int *numParams)
2370{
2371 if (!ValidateRobustEntryPoint(context, bufSize))
2372 {
2373 return false;
2374 }
2375
2376 if (!ValidateStateQuery(context, pname, nativeType, numParams))
2377 {
2378 return false;
2379 }
2380
2381 if (!ValidateRobustBufferSize(context, bufSize, *numParams))
Jamie Madill893ab082014-05-16 16:56:10 -04002382 {
2383 return false;
2384 }
2385
2386 return true;
2387}
2388
Jamie Madill5b772312018-03-08 20:28:32 -05002389bool ValidateCopyTexImageParametersBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002390 TextureTarget target,
Jamie Madillc29968b2016-01-20 11:17:23 -05002391 GLint level,
2392 GLenum internalformat,
2393 bool isSubImage,
2394 GLint xoffset,
2395 GLint yoffset,
2396 GLint zoffset,
2397 GLint x,
2398 GLint y,
2399 GLsizei width,
2400 GLsizei height,
2401 GLint border,
Jamie Madill0c8abca2016-07-22 20:21:26 -04002402 Format *textureFormatOut)
Jamie Madill560a8d82014-05-21 13:06:20 -04002403{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002404 TextureType texType = TextureTargetToType(target);
2405
Brandon Jones6cad5662017-06-14 13:25:13 -07002406 if (xoffset < 0 || yoffset < 0 || zoffset < 0)
Jamie Madill560a8d82014-05-21 13:06:20 -04002407 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002408 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
2409 return false;
2410 }
2411
2412 if (width < 0 || height < 0)
2413 {
2414 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Langb1196682014-07-23 13:47:29 -04002415 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002416 }
2417
He Yunchaoced53ae2016-11-29 15:00:51 +08002418 if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
2419 std::numeric_limits<GLsizei>::max() - yoffset < height)
Jamie Madill560a8d82014-05-21 13:06:20 -04002420 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002421 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002422 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002423 }
2424
2425 if (border != 0)
2426 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002427 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04002428 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002429 }
2430
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002431 if (!ValidMipLevel(context, texType, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002432 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002433 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Langb1196682014-07-23 13:47:29 -04002434 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002435 }
2436
Jamie Madill43da7c42018-08-01 11:34:49 -04002437 const State &state = context->getGLState();
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002438 Framebuffer *readFramebuffer = state.getReadFramebuffer();
Jamie Madill427064d2018-04-13 16:20:34 -04002439 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002440 {
Geoff Langb1196682014-07-23 13:47:29 -04002441 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002442 }
2443
Jamie Madille98b1b52018-03-08 09:47:23 -05002444 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madill560a8d82014-05-21 13:06:20 -04002445 {
Geoff Langb1196682014-07-23 13:47:29 -04002446 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002447 }
2448
Martin Radev138064f2016-07-15 12:03:41 +03002449 if (readFramebuffer->getReadBufferState() == GL_NONE)
2450 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Martin Radev138064f2016-07-15 12:03:41 +03002452 return false;
2453 }
2454
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002455 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
2456 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
He Yunchao66a41a22016-12-15 16:45:05 +08002457 // attachment and WebGL defines it to be an error. We do the check unconditionally as the
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002458 // situation is an application error that would lead to a crash in ANGLE.
Martin Radev04e2c3b2017-07-27 16:54:35 +03002459 const FramebufferAttachment *source = readFramebuffer->getReadColorbuffer();
2460 if (source == nullptr)
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002461 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment);
Corentin Wallez3c90ed62016-12-16 16:19:28 -05002463 return false;
2464 }
2465
Martin Radev04e2c3b2017-07-27 16:54:35 +03002466 // ANGLE_multiview spec, Revision 1:
2467 // Calling CopyTexSubImage3D, CopyTexImage2D, or CopyTexSubImage2D will result in an
2468 // INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the current read framebuffer
Olli Etuaho8acb1b62018-07-30 16:20:54 +03002469 // is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views in the current read
2470 // framebuffer is more than one.
2471 if (readFramebuffer->readDisallowedByMultiview())
Martin Radev04e2c3b2017-07-27 16:54:35 +03002472 {
2473 context->handleError(InvalidFramebufferOperation()
2474 << "The active read framebuffer object has multiview attachments.");
2475 return false;
2476 }
2477
Jamie Madill43da7c42018-08-01 11:34:49 -04002478 const Caps &caps = context->getCaps();
Geoff Langaae65a42014-05-26 12:43:44 -04002479
Geoff Langaae65a42014-05-26 12:43:44 -04002480 GLuint maxDimension = 0;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002481 switch (texType)
Jamie Madill560a8d82014-05-21 13:06:20 -04002482 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002483 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002484 maxDimension = caps.max2DTextureSize;
2485 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002486
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002487 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08002488 maxDimension = caps.maxCubeMapTextureSize;
2489 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002490
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002491 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002492 maxDimension = caps.maxRectangleTextureSize;
2493 break;
2494
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002495 case TextureType::_2DArray:
He Yunchaoced53ae2016-11-29 15:00:51 +08002496 maxDimension = caps.max2DTextureSize;
2497 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002498
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002499 case TextureType::_3D:
He Yunchaoced53ae2016-11-29 15:00:51 +08002500 maxDimension = caps.max3DTextureSize;
2501 break;
Jamie Madill560a8d82014-05-21 13:06:20 -04002502
He Yunchaoced53ae2016-11-29 15:00:51 +08002503 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002504 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08002505 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002506 }
2507
Jamie Madill43da7c42018-08-01 11:34:49 -04002508 Texture *texture = state.getTargetTexture(texType);
Jamie Madill560a8d82014-05-21 13:06:20 -04002509 if (!texture)
2510 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04002512 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002513 }
2514
Geoff Lang69cce582015-09-17 13:20:36 -04002515 if (texture->getImmutableFormat() && !isSubImage)
Jamie Madill560a8d82014-05-21 13:06:20 -04002516 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002517 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04002518 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002519 }
2520
Jamie Madill43da7c42018-08-01 11:34:49 -04002521 const InternalFormat &formatInfo =
Geoff Lang86f81162017-10-30 15:10:45 -04002522 isSubImage ? *texture->getFormat(target, level).info
Jamie Madill43da7c42018-08-01 11:34:49 -04002523 : GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
Geoff Lang5d601382014-07-22 15:14:06 -04002524
Geoff Lang966c9402017-04-18 12:38:27 -04002525 if (formatInfo.depthBits > 0 || formatInfo.compressed)
Jamie Madill560a8d82014-05-21 13:06:20 -04002526 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002527 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05002528 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002529 }
2530
2531 if (isSubImage)
2532 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05002533 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
2534 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
2535 static_cast<size_t>(zoffset) >= texture->getDepth(target, level))
Jamie Madill560a8d82014-05-21 13:06:20 -04002536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002537 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04002538 return false;
Jamie Madill560a8d82014-05-21 13:06:20 -04002539 }
2540 }
Jamie Madill6f38f822014-06-06 17:12:20 -04002541 else
2542 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002543 if (texType == TextureType::CubeMap && width != height)
Jamie Madill6f38f822014-06-06 17:12:20 -04002544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002545 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapIncomplete);
Geoff Langb1196682014-07-23 13:47:29 -04002546 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002547 }
2548
Geoff Langeb66a6e2016-10-31 13:06:12 -04002549 if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Jamie Madill6f38f822014-06-06 17:12:20 -04002550 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002551 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04002552 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002553 }
2554
2555 int maxLevelDimension = (maxDimension >> level);
He Yunchaoced53ae2016-11-29 15:00:51 +08002556 if (static_cast<int>(width) > maxLevelDimension ||
2557 static_cast<int>(height) > maxLevelDimension)
Jamie Madill6f38f822014-06-06 17:12:20 -04002558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002559 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04002560 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04002561 }
2562 }
Jamie Madill560a8d82014-05-21 13:06:20 -04002563
Jamie Madill0c8abca2016-07-22 20:21:26 -04002564 if (textureFormatOut)
2565 {
2566 *textureFormatOut = texture->getFormat(target, level);
2567 }
Jamie Madillf695a3a2017-01-11 17:36:35 -05002568
2569 // Detect texture copying feedback loops for WebGL.
2570 if (context->getExtensions().webglCompatibility)
2571 {
Jamie Madillfd3dd432017-02-02 19:59:59 -05002572 if (readFramebuffer->formsCopyingFeedbackLoopWith(texture->id(), level, zoffset))
Jamie Madillf695a3a2017-01-11 17:36:35 -05002573 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002574 ANGLE_VALIDATION_ERR(context, InvalidOperation(), FeedbackLoop);
Jamie Madillf695a3a2017-01-11 17:36:35 -05002575 return false;
2576 }
2577 }
2578
Jamie Madill560a8d82014-05-21 13:06:20 -04002579 return true;
2580}
2581
Jamie Madillb42162f2018-08-20 12:58:37 -04002582// Note all errors returned from this function are INVALID_OPERATION except for the draw framebuffer
2583// completeness check.
2584const char *ValidateDrawStates(Context *context)
Jamie Madille7d80f32018-08-08 15:49:23 -04002585{
2586 const Extensions &extensions = context->getExtensions();
Jamie Madill7f232932018-09-12 11:03:06 -04002587 const State &state = context->getGLState();
Jamie Madille7d80f32018-08-08 15:49:23 -04002588
2589 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange, FlushMappedBufferRange,
2590 // and UnmapBuffer entry points are removed from the WebGL 2.0 API.
2591 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
Jamie Madilld84b6732018-09-06 15:54:35 -04002592 VertexArray *vertexArray = state.getVertexArray();
2593 ASSERT(vertexArray);
2594
2595 if (!extensions.webglCompatibility && vertexArray->hasMappedEnabledArrayBuffer())
Jamie Madille7d80f32018-08-08 15:49:23 -04002596 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002597 return kErrorBufferMapped;
Jamie Madille7d80f32018-08-08 15:49:23 -04002598 }
2599
2600 // Note: these separate values are not supported in WebGL, due to D3D's limitations. See
2601 // Section 6.10 of the WebGL 1.0 spec.
2602 Framebuffer *framebuffer = state.getDrawFramebuffer();
Jamie Madilld84b6732018-09-06 15:54:35 -04002603 ASSERT(framebuffer);
2604
Jamie Madille7d80f32018-08-08 15:49:23 -04002605 if (context->getLimitations().noSeparateStencilRefsAndMasks || extensions.webglCompatibility)
2606 {
2607 ASSERT(framebuffer);
2608 const FramebufferAttachment *dsAttachment =
2609 framebuffer->getStencilOrDepthStencilAttachment();
2610 const GLuint stencilBits = dsAttachment ? dsAttachment->getStencilSize() : 0;
2611 ASSERT(stencilBits <= 8);
2612
2613 const DepthStencilState &depthStencilState = state.getDepthStencilState();
2614 if (depthStencilState.stencilTest && stencilBits > 0)
2615 {
2616 GLuint maxStencilValue = (1 << stencilBits) - 1;
2617
2618 bool differentRefs =
2619 clamp(state.getStencilRef(), 0, static_cast<GLint>(maxStencilValue)) !=
2620 clamp(state.getStencilBackRef(), 0, static_cast<GLint>(maxStencilValue));
2621 bool differentWritemasks = (depthStencilState.stencilWritemask & maxStencilValue) !=
2622 (depthStencilState.stencilBackWritemask & maxStencilValue);
2623 bool differentMasks = (depthStencilState.stencilMask & maxStencilValue) !=
2624 (depthStencilState.stencilBackMask & maxStencilValue);
2625
2626 if (differentRefs || differentWritemasks || differentMasks)
2627 {
2628 if (!extensions.webglCompatibility)
2629 {
2630 WARN() << "This ANGLE implementation does not support separate front/back "
2631 "stencil writemasks, reference values, or stencil mask values.";
2632 }
Jamie Madillb42162f2018-08-20 12:58:37 -04002633 return kErrorStencilReferenceMaskOrMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002634 }
2635 }
2636 }
2637
2638 if (!framebuffer->isComplete(context))
2639 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002640 // Note: this error should be generated as INVALID_FRAMEBUFFER_OPERATION.
2641 return kErrorDrawFramebufferIncomplete;
Jamie Madille7d80f32018-08-08 15:49:23 -04002642 }
2643
2644 if (context->getStateCache().hasAnyEnabledClientAttrib())
2645 {
2646 if (context->getExtensions().webglCompatibility || !state.areClientArraysEnabled())
2647 {
2648 // [WebGL 1.0] Section 6.5 Enabled Vertex Attributes and Range Checking
2649 // If a vertex attribute is enabled as an array via enableVertexAttribArray but no
2650 // buffer is bound to that attribute via bindBuffer and vertexAttribPointer, then calls
2651 // to drawArrays or drawElements will generate an INVALID_OPERATION error.
Jamie Madillb42162f2018-08-20 12:58:37 -04002652 return kErrorVertexArrayNoBuffer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002653 }
2654
2655 if (state.getVertexArray()->hasEnabledNullPointerClientArray())
2656 {
2657 // This is an application error that would normally result in a crash, but we catch it
2658 // and return an error
Jamie Madillb42162f2018-08-20 12:58:37 -04002659 return kErrorVertexArrayNoBufferPointer;
Jamie Madille7d80f32018-08-08 15:49:23 -04002660 }
2661 }
2662
2663 // If we are running GLES1, there is no current program.
2664 if (context->getClientVersion() >= Version(2, 0))
2665 {
Jamie Madill785e8a02018-10-04 17:42:00 -04002666 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002667 if (!program)
2668 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002669 return kErrorProgramNotBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002670 }
2671
2672 // In OpenGL ES spec for UseProgram at section 7.3, trying to render without
2673 // vertex shader stage or fragment shader stage is a undefined behaviour.
2674 // But ANGLE should clearly generate an INVALID_OPERATION error instead of
2675 // produce undefined result.
2676 if (!program->hasLinkedShaderStage(ShaderType::Vertex) ||
2677 !program->hasLinkedShaderStage(ShaderType::Fragment))
2678 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002679 return kErrorNoActiveGraphicsShaderStage;
Jamie Madille7d80f32018-08-08 15:49:23 -04002680 }
2681
2682 if (!program->validateSamplers(nullptr, context->getCaps()))
2683 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002684 return kErrorTextureTypeConflict;
Jamie Madille7d80f32018-08-08 15:49:23 -04002685 }
2686
2687 if (extensions.multiview)
2688 {
2689 const int programNumViews = program->usesMultiview() ? program->getNumViews() : 1;
2690 const int framebufferNumViews = framebuffer->getNumViews();
2691 if (framebufferNumViews != programNumViews)
2692 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002693 return kErrorMultiviewMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002694 }
2695
2696 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2697 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2698 framebufferNumViews > 1)
2699 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002700 return kErrorMultiviewTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002701 }
2702
2703 if (extensions.disjointTimerQuery && framebufferNumViews > 1 &&
2704 state.isQueryActive(QueryType::TimeElapsed))
2705 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002706 return kErrorMultiviewTimerQuery;
Jamie Madille7d80f32018-08-08 15:49:23 -04002707 }
2708 }
2709
2710 // Uniform buffer validation
2711 for (unsigned int uniformBlockIndex = 0;
2712 uniformBlockIndex < program->getActiveUniformBlockCount(); uniformBlockIndex++)
2713 {
2714 const InterfaceBlock &uniformBlock = program->getUniformBlockByIndex(uniformBlockIndex);
Jamie Madill7f232932018-09-12 11:03:06 -04002715 GLuint blockBinding = program->getUniformBlockBinding(uniformBlockIndex);
Jamie Madille7d80f32018-08-08 15:49:23 -04002716 const OffsetBindingPointer<Buffer> &uniformBuffer =
2717 state.getIndexedUniformBuffer(blockBinding);
2718
2719 if (uniformBuffer.get() == nullptr)
2720 {
2721 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002722 return kErrorUniformBufferUnbound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002723 }
2724
2725 size_t uniformBufferSize = GetBoundBufferAvailableSize(uniformBuffer);
2726 if (uniformBufferSize < uniformBlock.dataSize)
2727 {
2728 // undefined behaviour
Jamie Madillb42162f2018-08-20 12:58:37 -04002729 return kErrorUniformBufferTooSmall;
Jamie Madille7d80f32018-08-08 15:49:23 -04002730 }
2731
2732 if (extensions.webglCompatibility &&
2733 uniformBuffer->isBoundForTransformFeedbackAndOtherUse())
2734 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002735 return kErrorUniformBufferBoundForTransformFeedback;
Jamie Madille7d80f32018-08-08 15:49:23 -04002736 }
2737 }
2738
2739 // Do some additonal WebGL-specific validation
2740 if (extensions.webglCompatibility)
2741 {
2742 const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
2743 if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
2744 transformFeedbackObject->buffersBoundForOtherUse())
2745 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002746 return kErrorTransformFeedbackBufferDoubleBound;
Jamie Madille7d80f32018-08-08 15:49:23 -04002747 }
2748
2749 // Detect rendering feedback loops for WebGL.
2750 if (framebuffer->formsRenderingFeedbackLoopWith(state))
2751 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002752 return kErrorFeedbackLoop;
Jamie Madille7d80f32018-08-08 15:49:23 -04002753 }
2754
2755 // Detect that the vertex shader input types match the attribute types
2756 if (!ValidateVertexShaderAttributeTypeMatch(context))
2757 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002758 return kErrorVertexShaderTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002759 }
2760
2761 // Detect that the color buffer types match the fragment shader output types
2762 if (!ValidateFragmentShaderColorBufferTypeMatch(context))
2763 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002764 return kErrorDrawBufferTypeMismatch;
Jamie Madille7d80f32018-08-08 15:49:23 -04002765 }
Jamie Madill03cb5262018-08-08 15:49:24 -04002766
2767 const VertexArray *vao = context->getGLState().getVertexArray();
2768 if (vao->hasTransformFeedbackBindingConflict(context))
2769 {
Jamie Madillb42162f2018-08-20 12:58:37 -04002770 return kErrorVertexBufferBoundForTransformFeedback;
Jamie Madill03cb5262018-08-08 15:49:24 -04002771 }
Jamie Madille7d80f32018-08-08 15:49:23 -04002772 }
2773 }
2774
Jamie Madillb42162f2018-08-20 12:58:37 -04002775 return nullptr;
Jamie Madille7d80f32018-08-08 15:49:23 -04002776}
2777
Jamie Madill16e28fd2018-09-12 11:03:05 -04002778bool ValidateDrawMode(Context *context, PrimitiveMode mode)
Jamie Madill250d33f2014-06-06 17:09:03 -04002779{
Jiawei Shaofccebff2018-03-08 13:51:02 +08002780 const Extensions &extensions = context->getExtensions();
2781
Jamie Madill1aeb1312014-06-20 13:21:25 -04002782 switch (mode)
2783 {
Jamie Madill493f9572018-05-24 19:52:15 -04002784 case PrimitiveMode::Points:
2785 case PrimitiveMode::Lines:
2786 case PrimitiveMode::LineLoop:
2787 case PrimitiveMode::LineStrip:
2788 case PrimitiveMode::Triangles:
2789 case PrimitiveMode::TriangleStrip:
2790 case PrimitiveMode::TriangleFan:
He Yunchaoced53ae2016-11-29 15:00:51 +08002791 break;
Jiawei Shaofccebff2018-03-08 13:51:02 +08002792
Jamie Madill493f9572018-05-24 19:52:15 -04002793 case PrimitiveMode::LinesAdjacency:
2794 case PrimitiveMode::LineStripAdjacency:
2795 case PrimitiveMode::TrianglesAdjacency:
2796 case PrimitiveMode::TriangleStripAdjacency:
Jiawei Shaofccebff2018-03-08 13:51:02 +08002797 if (!extensions.geometryShader)
2798 {
2799 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
2800 return false;
2801 }
2802 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08002803 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002804 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDrawMode);
He Yunchaoced53ae2016-11-29 15:00:51 +08002805 return false;
Jamie Madill1aeb1312014-06-20 13:21:25 -04002806 }
2807
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002808 // If we are running GLES1, there is no current program.
2809 if (context->getClientVersion() >= Version(2, 0))
Jamie Madilld4cfa572014-07-08 10:00:32 -04002810 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002811 const State &state = context->getGLState();
2812
Jamie Madill785e8a02018-10-04 17:42:00 -04002813 Program *program = state.getLinkedProgram(context);
Jamie Madille7d80f32018-08-08 15:49:23 -04002814 ASSERT(program);
James Darpiniane8a93c62018-01-04 18:02:24 -08002815
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002816 // Do geometry shader specific validations
2817 if (program->hasLinkedShaderStage(ShaderType::Geometry))
James Darpiniane8a93c62018-01-04 18:02:24 -08002818 {
Lingfeng Yang461b09a2018-04-23 09:02:09 -07002819 if (!IsCompatibleDrawModeWithGeometryShader(
2820 mode, program->getGeometryShaderInputPrimitiveType()))
2821 {
2822 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2823 IncompatibleDrawModeAgainstGeometryShader);
2824 return false;
2825 }
Jamie Madilla4595b82017-01-11 17:36:34 -05002826 }
2827 }
2828
Jamie Madill9fdaa492018-02-16 10:52:11 -05002829 return true;
Jamie Madill250d33f2014-06-06 17:09:03 -04002830}
2831
Jamie Madill16e28fd2018-09-12 11:03:05 -04002832bool ValidateDrawBase(Context *context, PrimitiveMode mode, GLsizei count)
2833{
2834 if (!context->getStateCache().isValidDrawMode(mode))
2835 {
2836 return ValidateDrawMode(context, mode);
2837 }
2838
2839 if (count < 0)
2840 {
2841 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
2842 return false;
2843 }
2844
2845 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2846 if (drawStatesError)
2847 {
2848 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2849
2850 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2851 // Incomplete.
2852 GLenum errorCode =
2853 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2854 : GL_INVALID_OPERATION);
2855 context->handleError(Error(errorCode, errorMessage));
2856 return false;
2857 }
2858
2859 return true;
2860}
2861
Jamie Madill5b772312018-03-08 20:28:32 -05002862bool ValidateDrawArraysCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002863 PrimitiveMode mode,
Jamie Madillc1d770e2017-04-13 17:31:24 -04002864 GLint first,
2865 GLsizei count,
2866 GLsizei primcount)
Jamie Madill250d33f2014-06-06 17:09:03 -04002867{
Jamie Madillfd716582014-06-06 17:09:04 -04002868 if (first < 0)
Jamie Madill250d33f2014-06-06 17:09:03 -04002869 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002870 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStart);
Geoff Langb1196682014-07-23 13:47:29 -04002871 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002872 }
2873
Jamie Madill16e28fd2018-09-12 11:03:05 -04002874 if (count < 0)
2875 {
2876 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
2877 return false;
2878 }
2879
Jamie Madill7f232932018-09-12 11:03:06 -04002880 const State &state = context->getGLState();
2881 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002882 if (curTransformFeedback && curTransformFeedback->isActive() &&
James Darpinian30b604d2018-03-12 17:26:57 -07002883 !curTransformFeedback->isPaused())
Jamie Madillfd716582014-06-06 17:09:04 -04002884 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002885 if (!ValidateTransformFeedbackPrimitiveMode(context,
2886 curTransformFeedback->getPrimitiveMode(), mode))
James Darpinian30b604d2018-03-12 17:26:57 -07002887 {
James Darpinian30b604d2018-03-12 17:26:57 -07002888 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
2889 return false;
2890 }
2891
2892 if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
2893 {
2894 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TransformFeedbackBufferTooSmall);
2895 return false;
2896 }
Jamie Madillfd716582014-06-06 17:09:04 -04002897 }
2898
Jamie Madill16e28fd2018-09-12 11:03:05 -04002899 if (!context->getStateCache().isValidDrawMode(mode))
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002900 {
Jamie Madill16e28fd2018-09-12 11:03:05 -04002901 return ValidateDrawMode(context, mode);
2902 }
2903
2904 intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
2905 if (drawStatesError)
2906 {
2907 const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
2908
2909 // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
2910 // Incomplete.
2911 GLenum errorCode =
2912 (errorMessage == kErrorDrawFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION
2913 : GL_INVALID_OPERATION);
2914 context->handleError(Error(errorCode, errorMessage));
Corentin Wallez18a2fb32015-08-10 12:58:14 -07002915 return false;
2916 }
2917
Corentin Wallez71168a02016-12-19 15:11:18 -08002918 // Check the computation of maxVertex doesn't overflow.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002919 // - first < 0 has been checked as an error condition.
2920 // - if count < 0, skip validating no-op draw calls.
Corentin Wallez71168a02016-12-19 15:11:18 -08002921 // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
Jamie Madill9fdaa492018-02-16 10:52:11 -05002922 ASSERT(first >= 0);
Jamie Madill2da53562018-08-01 11:34:47 -04002923 if (count > 0 && primcount > 0)
Corentin Wallez92db6942016-12-09 13:10:36 -05002924 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05002925 int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
2926 if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
2927 {
2928 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
2929 return false;
2930 }
Corentin Wallez92db6942016-12-09 13:10:36 -05002931
Jamie Madill2da53562018-08-01 11:34:47 -04002932 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(maxVertex)))
Jamie Madill9fdaa492018-02-16 10:52:11 -05002933 {
2934 return false;
2935 }
Jamie Madillfd716582014-06-06 17:09:04 -04002936 }
2937
2938 return true;
2939}
2940
He Yunchaoced53ae2016-11-29 15:00:51 +08002941bool ValidateDrawArraysInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04002942 PrimitiveMode mode,
He Yunchaoced53ae2016-11-29 15:00:51 +08002943 GLint first,
2944 GLsizei count,
2945 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04002946{
Geoff Lang63c5a592017-09-27 14:08:16 -04002947 if (!context->getExtensions().instancedArrays)
2948 {
2949 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
2950 return false;
2951 }
2952
Corentin Wallez170efbf2017-05-02 13:45:01 -04002953 if (!ValidateDrawArraysInstancedBase(context, mode, first, count, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04002954 {
2955 return false;
2956 }
2957
Corentin Wallez0dc97812017-06-22 14:38:44 -04002958 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04002959}
2960
Jamie Madill493f9572018-05-24 19:52:15 -04002961bool ValidateDrawElementsBase(Context *context, PrimitiveMode mode, GLenum type)
Jamie Madillfd716582014-06-06 17:09:04 -04002962{
Jamie Madill250d33f2014-06-06 17:09:03 -04002963 switch (type)
2964 {
He Yunchaoced53ae2016-11-29 15:00:51 +08002965 case GL_UNSIGNED_BYTE:
2966 case GL_UNSIGNED_SHORT:
2967 break;
2968 case GL_UNSIGNED_INT:
2969 if (context->getClientMajorVersion() < 3 && !context->getExtensions().elementIndexUint)
2970 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002971 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002972 return false;
2973 }
2974 break;
2975 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002976 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TypeNotUnsignedShortByte);
He Yunchaoced53ae2016-11-29 15:00:51 +08002977 return false;
Jamie Madill250d33f2014-06-06 17:09:03 -04002978 }
2979
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002980 const State &state = context->getGLState();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002981
Jamie Madill43da7c42018-08-01 11:34:49 -04002982 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
He Yunchaoced53ae2016-11-29 15:00:51 +08002983 if (curTransformFeedback && curTransformFeedback->isActive() &&
2984 !curTransformFeedback->isPaused())
Jamie Madill250d33f2014-06-06 17:09:03 -04002985 {
Jiawei Shao80c32cc2018-04-25 09:48:36 +08002986 // EXT_geometry_shader allows transform feedback to work with all draw commands.
2987 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
2988 if (context->getExtensions().geometryShader)
2989 {
2990 if (!ValidateTransformFeedbackPrimitiveMode(
2991 context, curTransformFeedback->getPrimitiveMode(), mode))
2992 {
2993 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDrawModeTransformFeedback);
2994 return false;
2995 }
2996 }
2997 else
2998 {
2999 // It is an invalid operation to call DrawElements, DrawRangeElements or
3000 // DrawElementsInstanced while transform feedback is active, (3.0.2, section 2.14, pg
3001 // 86)
3002 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
3003 UnsupportedDrawModeForTransformFeedback);
3004 return false;
3005 }
Jamie Madill250d33f2014-06-06 17:09:03 -04003006 }
3007
Jiajia Qind9671222016-11-29 16:30:31 +08003008 return true;
3009}
3010
Jamie Madill5b772312018-03-08 20:28:32 -05003011bool ValidateDrawElementsCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003012 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003013 GLsizei count,
3014 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003015 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003016 GLsizei primcount)
Jiajia Qind9671222016-11-29 16:30:31 +08003017{
Jiawei Shao80c32cc2018-04-25 09:48:36 +08003018 if (!ValidateDrawElementsBase(context, mode, type))
Jiajia Qind9671222016-11-29 16:30:31 +08003019 return false;
3020
3021 const State &state = context->getGLState();
3022
Corentin Wallez170efbf2017-05-02 13:45:01 -04003023 if (!ValidateDrawBase(context, mode, count))
3024 {
3025 return false;
3026 }
3027
Jamie Madill43da7c42018-08-01 11:34:49 -04003028 const VertexArray *vao = state.getVertexArray();
Jamie Madillcd0a0a32018-10-18 18:41:57 -04003029 Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
Jamie Madilld4cfa572014-07-08 10:00:32 -04003030
Jamie Madill43da7c42018-08-01 11:34:49 -04003031 GLuint typeBytes = GetTypeInfo(type).bytes;
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003032
3033 if (context->getExtensions().webglCompatibility)
3034 {
3035 ASSERT(isPow2(typeBytes) && typeBytes > 0);
3036 if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
3037 {
3038 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3039 // The offset arguments to drawElements and [...], must be a multiple of the size of the
3040 // data type passed to the call, or an INVALID_OPERATION error is generated.
Brandon Jones6cad5662017-06-14 13:25:13 -07003041 ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfType);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003042 return false;
3043 }
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003044
3045 // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
3046 // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
3047 // error is generated.
3048 if (reinterpret_cast<intptr_t>(indices) < 0)
3049 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003050 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Corentin Wallezfe9306a2017-02-01 17:41:05 -05003051 return false;
3052 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003053 }
Jamie Madillcc73f242018-08-01 11:34:48 -04003054 else if (elementArrayBuffer && elementArrayBuffer->isMapped())
3055 {
3056 // WebGL buffers cannot be mapped/unmapped because the MapBufferRange,
3057 // FlushMappedBufferRange, and UnmapBuffer entry points are removed from the WebGL 2.0 API.
3058 // https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.14
3059 context->handleError(InvalidOperation() << "Index buffer is mapped.");
3060 return false;
3061 }
Geoff Langfeb8c682017-02-13 16:07:35 -05003062
3063 if (context->getExtensions().webglCompatibility ||
3064 !context->getGLState().areClientArraysEnabled())
3065 {
Brandon Jones2a018152018-06-08 15:59:26 -07003066 if (!elementArrayBuffer)
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003067 {
3068 // [WebGL 1.0] Section 6.2 No Client Side Arrays
Brandon Jones2a018152018-06-08 15:59:26 -07003069 // If an indexed draw command (drawElements) is called and no WebGLBuffer is bound to
3070 // the ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated.
Brandon Jones6cad5662017-06-14 13:25:13 -07003071 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MustHaveElementArrayBinding);
Corentin Wallez3f6d4df2017-01-30 18:04:36 -05003072 return false;
3073 }
3074 }
3075
Jamie Madill9fdaa492018-02-16 10:52:11 -05003076 if (count > 0 && !elementArrayBuffer && !indices)
Jamie Madillae3000b2014-08-25 15:47:51 -04003077 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003078 // This is an application error that would normally result in a crash, but we catch it and
3079 // return an error
3080 context->handleError(InvalidOperation() << "No element array buffer and no pointer.");
3081 return false;
3082 }
3083
3084 if (count > 0 && elementArrayBuffer)
3085 {
3086 // The max possible type size is 8 and count is on 32 bits so doing the multiplication
3087 // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
3088 static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
3089 constexpr uint64_t kMaxTypeSize = 8;
3090 constexpr uint64_t kIntMax = std::numeric_limits<int>::max();
3091 constexpr uint64_t kUint64Max = std::numeric_limits<uint64_t>::max();
3092 static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
3093
3094 uint64_t typeSize = typeBytes;
3095 uint64_t elementCount = static_cast<uint64_t>(count);
3096 ASSERT(elementCount > 0 && typeSize <= kMaxTypeSize);
3097
3098 // Doing the multiplication here is overflow-safe
3099 uint64_t elementDataSizeNoOffset = typeSize * elementCount;
3100
3101 // The offset can be any value, check for overflows
3102 uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
3103 if (elementDataSizeNoOffset > kUint64Max - offset)
Jamie Madillae3000b2014-08-25 15:47:51 -04003104 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003105 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
3106 return false;
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003107 }
Jamie Madill9fdaa492018-02-16 10:52:11 -05003108
3109 uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
3110 if (elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize()))
Corentin Wallez0844f2d2017-01-31 17:02:59 -05003111 {
Jamie Madill9fdaa492018-02-16 10:52:11 -05003112 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
3113 return false;
3114 }
3115
3116 ASSERT(isPow2(typeSize) && typeSize > 0);
3117 if ((elementArrayBuffer->getSize() & (typeSize - 1)) != 0)
3118 {
3119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedByteCountType);
Geoff Langb1196682014-07-23 13:47:29 -04003120 return false;
Jamie Madillae3000b2014-08-25 15:47:51 -04003121 }
James Darpiniane8a93c62018-01-04 18:02:24 -08003122
3123 if (context->getExtensions().webglCompatibility &&
3124 elementArrayBuffer->isBoundForTransformFeedbackAndOtherUse())
3125 {
3126 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
3127 ElementArrayBufferBoundForTransformFeedback);
3128 return false;
3129 }
Jamie Madillae3000b2014-08-25 15:47:51 -04003130 }
3131
Jamie Madill2da53562018-08-01 11:34:47 -04003132 if (!context->getExtensions().robustBufferAccessBehavior && count > 0 && primcount > 0)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003133 {
3134 // Use the parameter buffer to retrieve and cache the index range.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003135 const DrawCallParams &params = context->getParams<DrawCallParams>();
3136 ANGLE_VALIDATION_TRY(params.ensureIndexRangeResolved(context));
3137 const IndexRange &indexRange = params.getIndexRange();
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003138
3139 // If we use an index greater than our maximum supported index range, return an error.
3140 // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should always
3141 // return an error if possible here.
Jamie Madill6f5444d2018-03-14 10:08:11 -04003142 if (static_cast<GLuint64>(indexRange.end) >= context->getCaps().maxElementIndex)
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003143 {
3144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExceedsMaxElement);
3145 return false;
3146 }
3147
Jamie Madill2da53562018-08-01 11:34:47 -04003148 if (!ValidateDrawAttribs(context, primcount, static_cast<GLint>(indexRange.end)))
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003149 {
3150 return false;
3151 }
3152
3153 // No op if there are no real indices in the index data (all are primitive restart).
Jamie Madill6f5444d2018-03-14 10:08:11 -04003154 return (indexRange.vertexIndexCount > 0);
Corentin Wallezc1346fb2017-08-24 16:11:26 +00003155 }
3156
Jiajia Qin8a7b3a02017-08-25 16:05:48 +08003157 return true;
Jamie Madillfd716582014-06-06 17:09:04 -04003158}
3159
Jamie Madill5b772312018-03-08 20:28:32 -05003160bool ValidateDrawElementsInstancedCommon(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003161 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003162 GLsizei count,
3163 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003164 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003165 GLsizei primcount)
Jamie Madillfd716582014-06-06 17:09:04 -04003166{
Corentin Wallez0dc97812017-06-22 14:38:44 -04003167 return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount);
Jamie Madill250d33f2014-06-06 17:09:03 -04003168}
3169
Geoff Lang3edfe032015-09-04 16:38:24 -04003170bool ValidateDrawElementsInstancedANGLE(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04003171 PrimitiveMode mode,
Geoff Lang3edfe032015-09-04 16:38:24 -04003172 GLsizei count,
3173 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04003174 const void *indices,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04003175 GLsizei primcount)
Geoff Lang87a93302014-09-16 13:29:43 -04003176{
Geoff Lang63c5a592017-09-27 14:08:16 -04003177 if (!context->getExtensions().instancedArrays)
3178 {
3179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3180 return false;
3181 }
3182
Corentin Wallez170efbf2017-05-02 13:45:01 -04003183 if (!ValidateDrawElementsInstancedBase(context, mode, count, type, indices, primcount))
Geoff Lang87a93302014-09-16 13:29:43 -04003184 {
3185 return false;
3186 }
3187
Corentin Wallez0dc97812017-06-22 14:38:44 -04003188 return ValidateDrawInstancedANGLE(context);
Geoff Lang87a93302014-09-16 13:29:43 -04003189}
3190
He Yunchaoced53ae2016-11-29 15:00:51 +08003191bool ValidateFramebufferTextureBase(Context *context,
3192 GLenum target,
3193 GLenum attachment,
3194 GLuint texture,
3195 GLint level)
Jamie Madill570f7c82014-07-03 10:38:54 -04003196{
Geoff Lange8afa902017-09-27 15:00:43 -04003197 if (!ValidFramebufferTarget(context, target))
Jamie Madill55ec3b12014-07-03 10:38:57 -04003198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003199 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003200 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003201 }
3202
3203 if (!ValidateAttachmentTarget(context, attachment))
Jamie Madill570f7c82014-07-03 10:38:54 -04003204 {
3205 return false;
3206 }
3207
Jamie Madill55ec3b12014-07-03 10:38:57 -04003208 if (texture != 0)
3209 {
Jamie Madill43da7c42018-08-01 11:34:49 -04003210 Texture *tex = context->getTexture(texture);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003211
Luc Ferronadcf0ae2018-01-24 08:27:37 -05003212 if (tex == nullptr)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003214 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04003215 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003216 }
3217
3218 if (level < 0)
3219 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003220 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04003221 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003222 }
3223 }
3224
Jamie Madill43da7c42018-08-01 11:34:49 -04003225 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
Jamie Madill84115c92015-04-23 15:00:07 -04003226 ASSERT(framebuffer);
Jamie Madill55ec3b12014-07-03 10:38:57 -04003227
Jamie Madill84115c92015-04-23 15:00:07 -04003228 if (framebuffer->id() == 0)
Jamie Madill55ec3b12014-07-03 10:38:57 -04003229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003230 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langb1196682014-07-23 13:47:29 -04003231 return false;
Jamie Madill55ec3b12014-07-03 10:38:57 -04003232 }
3233
3234 return true;
3235}
3236
Geoff Langb1196682014-07-23 13:47:29 -04003237bool ValidateGetUniformBase(Context *context, GLuint program, GLint location)
Jamie Madill0063c512014-08-25 15:47:53 -04003238{
3239 if (program == 0)
3240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003241 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04003242 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003243 }
3244
Jamie Madill43da7c42018-08-01 11:34:49 -04003245 Program *programObject = GetValidProgram(context, program);
Dian Xiang769769a2015-09-09 15:20:08 -07003246 if (!programObject)
Shannon Woods4de4fd62014-11-07 16:22:02 -05003247 {
3248 return false;
3249 }
3250
Jamie Madill0063c512014-08-25 15:47:53 -04003251 if (!programObject || !programObject->isLinked())
3252 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003253 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Geoff Langb1196682014-07-23 13:47:29 -04003254 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003255 }
3256
Geoff Lang7dd2e102014-11-10 15:19:26 -05003257 if (!programObject->isValidUniformLocation(location))
Jamie Madill549c7fd2014-08-25 15:47:56 -04003258 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003259 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04003260 return false;
Jamie Madill549c7fd2014-08-25 15:47:56 -04003261 }
3262
Jamie Madill0063c512014-08-25 15:47:53 -04003263 return true;
3264}
3265
Geoff Langf41d0ee2016-10-07 13:04:23 -04003266static bool ValidateSizedGetUniform(Context *context,
3267 GLuint program,
3268 GLint location,
3269 GLsizei bufSize,
3270 GLsizei *length)
Jamie Madill78f41802014-08-25 15:47:55 -04003271{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003272 if (length)
3273 {
3274 *length = 0;
3275 }
3276
Jamie Madill78f41802014-08-25 15:47:55 -04003277 if (!ValidateGetUniformBase(context, program, location))
Jamie Madill0063c512014-08-25 15:47:53 -04003278 {
Jamie Madill78f41802014-08-25 15:47:55 -04003279 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003280 }
3281
Geoff Langf41d0ee2016-10-07 13:04:23 -04003282 if (bufSize < 0)
3283 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003284 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003285 return false;
3286 }
3287
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003288 Program *programObject = context->getProgramResolveLink(program);
Jamie Madilla502c742014-08-28 17:19:13 -04003289 ASSERT(programObject);
Jamie Madill0063c512014-08-25 15:47:53 -04003290
Jamie Madill78f41802014-08-25 15:47:55 -04003291 // sized queries -- ensure the provided buffer is large enough
Jamie Madill62d31cb2015-09-11 13:25:51 -04003292 const LinkedUniform &uniform = programObject->getUniformByLocation(location);
He Yunchaoced53ae2016-11-29 15:00:51 +08003293 size_t requiredBytes = VariableExternalSize(uniform.type);
Jamie Madill78f41802014-08-25 15:47:55 -04003294 if (static_cast<size_t>(bufSize) < requiredBytes)
Jamie Madill0063c512014-08-25 15:47:53 -04003295 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Geoff Langb1196682014-07-23 13:47:29 -04003297 return false;
Jamie Madill0063c512014-08-25 15:47:53 -04003298 }
3299
Geoff Langf41d0ee2016-10-07 13:04:23 -04003300 if (length)
3301 {
Geoff Lang94177fb2016-11-14 16:12:26 -05003302 *length = VariableComponentCount(uniform.type);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003303 }
3304
Jamie Madill0063c512014-08-25 15:47:53 -04003305 return true;
3306}
3307
He Yunchaoced53ae2016-11-29 15:00:51 +08003308bool ValidateGetnUniformfvEXT(Context *context,
3309 GLuint program,
3310 GLint location,
3311 GLsizei bufSize,
3312 GLfloat *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003313{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003314 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
Jamie Madill0063c512014-08-25 15:47:53 -04003315}
3316
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003317bool ValidateGetnUniformfvRobustANGLE(Context *context,
3318 GLuint program,
3319 GLint location,
3320 GLsizei bufSize,
3321 GLsizei *length,
3322 GLfloat *params)
3323{
3324 UNIMPLEMENTED();
3325 return false;
3326}
3327
He Yunchaoced53ae2016-11-29 15:00:51 +08003328bool ValidateGetnUniformivEXT(Context *context,
3329 GLuint program,
3330 GLint location,
3331 GLsizei bufSize,
3332 GLint *params)
Jamie Madill0063c512014-08-25 15:47:53 -04003333{
Geoff Langf41d0ee2016-10-07 13:04:23 -04003334 return ValidateSizedGetUniform(context, program, location, bufSize, nullptr);
3335}
3336
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07003337bool ValidateGetnUniformivRobustANGLE(Context *context,
3338 GLuint program,
3339 GLint location,
3340 GLsizei bufSize,
3341 GLsizei *length,
3342 GLint *params)
3343{
3344 UNIMPLEMENTED();
3345 return false;
3346}
3347
3348bool ValidateGetnUniformuivRobustANGLE(Context *context,
3349 GLuint program,
3350 GLint location,
3351 GLsizei bufSize,
3352 GLsizei *length,
3353 GLuint *params)
3354{
3355 UNIMPLEMENTED();
3356 return false;
3357}
3358
Geoff Langf41d0ee2016-10-07 13:04:23 -04003359bool ValidateGetUniformfvRobustANGLE(Context *context,
3360 GLuint program,
3361 GLint location,
3362 GLsizei bufSize,
3363 GLsizei *length,
3364 GLfloat *params)
3365{
3366 if (!ValidateRobustEntryPoint(context, bufSize))
3367 {
3368 return false;
3369 }
3370
Brandon Jonesd1049182018-03-28 10:02:20 -07003371 GLsizei writeLength = 0;
3372
Geoff Langf41d0ee2016-10-07 13:04:23 -04003373 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003374 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3375 {
3376 return false;
3377 }
3378
3379 SetRobustLengthParam(length, writeLength);
3380
3381 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003382}
3383
3384bool ValidateGetUniformivRobustANGLE(Context *context,
3385 GLuint program,
3386 GLint location,
3387 GLsizei bufSize,
3388 GLsizei *length,
3389 GLint *params)
3390{
3391 if (!ValidateRobustEntryPoint(context, bufSize))
3392 {
3393 return false;
3394 }
3395
Brandon Jonesd1049182018-03-28 10:02:20 -07003396 GLsizei writeLength = 0;
3397
Geoff Langf41d0ee2016-10-07 13:04:23 -04003398 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003399 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3400 {
3401 return false;
3402 }
3403
3404 SetRobustLengthParam(length, writeLength);
3405
3406 return true;
Geoff Langf41d0ee2016-10-07 13:04:23 -04003407}
3408
3409bool ValidateGetUniformuivRobustANGLE(Context *context,
3410 GLuint program,
3411 GLint location,
3412 GLsizei bufSize,
3413 GLsizei *length,
3414 GLuint *params)
3415{
3416 if (!ValidateRobustEntryPoint(context, bufSize))
3417 {
3418 return false;
3419 }
3420
3421 if (context->getClientMajorVersion() < 3)
3422 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08003423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
Geoff Langf41d0ee2016-10-07 13:04:23 -04003424 return false;
3425 }
3426
Brandon Jonesd1049182018-03-28 10:02:20 -07003427 GLsizei writeLength = 0;
3428
Geoff Langf41d0ee2016-10-07 13:04:23 -04003429 // bufSize is validated in ValidateSizedGetUniform
Brandon Jonesd1049182018-03-28 10:02:20 -07003430 if (!ValidateSizedGetUniform(context, program, location, bufSize, &writeLength))
3431 {
3432 return false;
3433 }
3434
3435 SetRobustLengthParam(length, writeLength);
3436
3437 return true;
Jamie Madill0063c512014-08-25 15:47:53 -04003438}
3439
He Yunchaoced53ae2016-11-29 15:00:51 +08003440bool ValidateDiscardFramebufferBase(Context *context,
3441 GLenum target,
3442 GLsizei numAttachments,
3443 const GLenum *attachments,
3444 bool defaultFramebuffer)
Austin Kinross08332632015-05-05 13:35:47 -07003445{
3446 if (numAttachments < 0)
3447 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003448 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeAttachments);
Austin Kinross08332632015-05-05 13:35:47 -07003449 return false;
3450 }
3451
3452 for (GLsizei i = 0; i < numAttachments; ++i)
3453 {
Olli Etuaho84c9f592016-03-09 14:37:25 +02003454 if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT31)
Austin Kinross08332632015-05-05 13:35:47 -07003455 {
3456 if (defaultFramebuffer)
3457 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003458 ANGLE_VALIDATION_ERR(context, InvalidEnum(), DefaultFramebufferInvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003459 return false;
3460 }
3461
3462 if (attachments[i] >= GL_COLOR_ATTACHMENT0 + context->getCaps().maxColorAttachments)
3463 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003464 context->handleError(InvalidOperation() << "Requested color attachment is "
3465 "greater than the maximum supported "
3466 "color attachments");
Austin Kinross08332632015-05-05 13:35:47 -07003467 return false;
3468 }
3469 }
3470 else
3471 {
3472 switch (attachments[i])
3473 {
He Yunchaoced53ae2016-11-29 15:00:51 +08003474 case GL_DEPTH_ATTACHMENT:
3475 case GL_STENCIL_ATTACHMENT:
3476 case GL_DEPTH_STENCIL_ATTACHMENT:
3477 if (defaultFramebuffer)
3478 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003479 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
3480 DefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003481 return false;
3482 }
3483 break;
3484 case GL_COLOR:
3485 case GL_DEPTH:
3486 case GL_STENCIL:
3487 if (!defaultFramebuffer)
3488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003489 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
3490 DefaultFramebufferInvalidAttachment);
He Yunchaoced53ae2016-11-29 15:00:51 +08003491 return false;
3492 }
3493 break;
3494 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003495 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Austin Kinross08332632015-05-05 13:35:47 -07003496 return false;
Austin Kinross08332632015-05-05 13:35:47 -07003497 }
3498 }
3499 }
3500
3501 return true;
3502}
3503
Austin Kinross6ee1e782015-05-29 17:05:37 -07003504bool ValidateInsertEventMarkerEXT(Context *context, GLsizei length, const char *marker)
3505{
Jamie Madill007530e2017-12-28 14:27:04 -05003506 if (!context->getExtensions().debugMarker)
3507 {
3508 // The debug marker calls should not set error state
3509 // However, it seems reasonable to set an error state if the extension is not enabled
3510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3511 return false;
3512 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003513
Jamie Madill007530e2017-12-28 14:27:04 -05003514 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003515 if (length < 0)
3516 {
3517 return false;
3518 }
3519
3520 if (marker == nullptr)
3521 {
3522 return false;
3523 }
3524
3525 return true;
3526}
3527
3528bool ValidatePushGroupMarkerEXT(Context *context, GLsizei length, const char *marker)
3529{
Jamie Madill007530e2017-12-28 14:27:04 -05003530 if (!context->getExtensions().debugMarker)
3531 {
3532 // The debug marker calls should not set error state
3533 // However, it seems reasonable to set an error state if the extension is not enabled
3534 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
3535 return false;
3536 }
Austin Kinross6ee1e782015-05-29 17:05:37 -07003537
Jamie Madill007530e2017-12-28 14:27:04 -05003538 // Note that debug marker calls must not set error state
Austin Kinross6ee1e782015-05-29 17:05:37 -07003539 if (length < 0)
3540 {
3541 return false;
3542 }
3543
3544 if (length > 0 && marker == nullptr)
3545 {
3546 return false;
3547 }
3548
3549 return true;
3550}
3551
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003552bool ValidateEGLImageTargetTexture2DOES(Context *context, TextureType type, GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003553{
Geoff Langa8406172015-07-21 16:53:39 -04003554 if (!context->getExtensions().eglImage && !context->getExtensions().eglImageExternal)
3555 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003556 context->handleError(InvalidOperation());
Geoff Langa8406172015-07-21 16:53:39 -04003557 return false;
3558 }
3559
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003560 switch (type)
Geoff Langa8406172015-07-21 16:53:39 -04003561 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003562 case TextureType::_2D:
Geoff Langb66a9092016-05-16 15:59:14 -04003563 if (!context->getExtensions().eglImage)
3564 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003565 context->handleError(InvalidEnum()
3566 << "GL_TEXTURE_2D texture target requires GL_OES_EGL_image.");
Geoff Langb66a9092016-05-16 15:59:14 -04003567 }
3568 break;
3569
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003570 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04003571 if (!context->getExtensions().eglImageExternal)
3572 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003573 context->handleError(InvalidEnum() << "GL_TEXTURE_EXTERNAL_OES texture target "
3574 "requires GL_OES_EGL_image_external.");
Geoff Langb66a9092016-05-16 15:59:14 -04003575 }
Geoff Langa8406172015-07-21 16:53:39 -04003576 break;
3577
3578 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003579 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003580 return false;
3581 }
3582
Rafael Cintron05a449a2018-06-20 18:08:04 -07003583 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003584
Jamie Madill61e16b42017-06-19 11:13:23 -04003585 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003586 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003588 context->handleError(InvalidValue() << "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003589 return false;
3590 }
3591
Jamie Madill007530e2017-12-28 14:27:04 -05003592 if (imageObject->getSamples() > 0)
Geoff Langa8406172015-07-21 16:53:39 -04003593 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003594 context->handleError(InvalidOperation()
3595 << "cannot create a 2D texture from a multisampled EGL image.");
Geoff Langa8406172015-07-21 16:53:39 -04003596 return false;
3597 }
3598
Yuly Novikov2eb54072018-08-22 16:41:26 -04003599 if (!imageObject->isTexturable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003600 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003601 context->handleError(InvalidOperation()
3602 << "EGL image internal format is not supported as a texture.");
Geoff Langa8406172015-07-21 16:53:39 -04003603 return false;
3604 }
3605
Geoff Langdcab33b2015-07-21 13:03:16 -04003606 return true;
3607}
3608
3609bool ValidateEGLImageTargetRenderbufferStorageOES(Context *context,
Geoff Langdcab33b2015-07-21 13:03:16 -04003610 GLenum target,
Jamie Madill007530e2017-12-28 14:27:04 -05003611 GLeglImageOES image)
Geoff Langdcab33b2015-07-21 13:03:16 -04003612{
Geoff Langa8406172015-07-21 16:53:39 -04003613 if (!context->getExtensions().eglImage)
3614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003615 context->handleError(InvalidOperation());
Geoff Langa8406172015-07-21 16:53:39 -04003616 return false;
3617 }
3618
3619 switch (target)
3620 {
3621 case GL_RENDERBUFFER:
3622 break;
3623
3624 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003625 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Geoff Langa8406172015-07-21 16:53:39 -04003626 return false;
3627 }
3628
Rafael Cintron05a449a2018-06-20 18:08:04 -07003629 egl::Image *imageObject = static_cast<egl::Image *>(image);
Jamie Madill007530e2017-12-28 14:27:04 -05003630
Jamie Madill61e16b42017-06-19 11:13:23 -04003631 ASSERT(context->getCurrentDisplay());
Jamie Madill007530e2017-12-28 14:27:04 -05003632 if (!context->getCurrentDisplay()->isValidImage(imageObject))
Geoff Langa8406172015-07-21 16:53:39 -04003633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003634 context->handleError(InvalidValue() << "EGL image is not valid.");
Geoff Langa8406172015-07-21 16:53:39 -04003635 return false;
3636 }
3637
Yuly Novikov2eb54072018-08-22 16:41:26 -04003638 if (!imageObject->isRenderable(context))
Geoff Langa8406172015-07-21 16:53:39 -04003639 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003640 context->handleError(InvalidOperation()
3641 << "EGL image internal format is not supported as a renderbuffer.");
Geoff Langa8406172015-07-21 16:53:39 -04003642 return false;
3643 }
3644
Geoff Langdcab33b2015-07-21 13:03:16 -04003645 return true;
3646}
Austin Kinrossbc781f32015-10-26 09:27:38 -07003647
3648bool ValidateBindVertexArrayBase(Context *context, GLuint array)
3649{
Geoff Lang36167ab2015-12-07 10:27:14 -05003650 if (!context->isVertexArrayGenerated(array))
Austin Kinrossbc781f32015-10-26 09:27:38 -07003651 {
3652 // The default VAO should always exist
3653 ASSERT(array != 0);
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003654 context->handleError(InvalidOperation());
Austin Kinrossbc781f32015-10-26 09:27:38 -07003655 return false;
3656 }
3657
3658 return true;
3659}
3660
Geoff Langc5629752015-12-07 16:29:04 -05003661bool ValidateProgramBinaryBase(Context *context,
3662 GLuint program,
3663 GLenum binaryFormat,
3664 const void *binary,
3665 GLint length)
3666{
3667 Program *programObject = GetValidProgram(context, program);
3668 if (programObject == nullptr)
3669 {
3670 return false;
3671 }
3672
3673 const std::vector<GLenum> &programBinaryFormats = context->getCaps().programBinaryFormats;
3674 if (std::find(programBinaryFormats.begin(), programBinaryFormats.end(), binaryFormat) ==
3675 programBinaryFormats.end())
3676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003677 context->handleError(InvalidEnum() << "Program binary format is not valid.");
Geoff Langc5629752015-12-07 16:29:04 -05003678 return false;
3679 }
3680
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003681 if (context->hasActiveTransformFeedback(program))
3682 {
3683 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003684 context->handleError(InvalidOperation() << "Cannot change program binary while program "
3685 "is associated with an active transform "
3686 "feedback object.");
Olli Etuahoc3e55a42016-03-09 16:29:18 +02003687 return false;
3688 }
3689
Geoff Langc5629752015-12-07 16:29:04 -05003690 return true;
3691}
3692
3693bool ValidateGetProgramBinaryBase(Context *context,
3694 GLuint program,
3695 GLsizei bufSize,
3696 GLsizei *length,
3697 GLenum *binaryFormat,
3698 void *binary)
3699{
3700 Program *programObject = GetValidProgram(context, program);
3701 if (programObject == nullptr)
3702 {
3703 return false;
3704 }
3705
3706 if (!programObject->isLinked())
3707 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003708 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Geoff Langc5629752015-12-07 16:29:04 -05003709 return false;
3710 }
3711
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003712 if (context->getCaps().programBinaryFormats.empty())
3713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003714 context->handleError(InvalidOperation() << "No program binary formats supported.");
Jamie Madilla7d12dc2016-12-13 15:08:19 -05003715 return false;
3716 }
3717
Geoff Langc5629752015-12-07 16:29:04 -05003718 return true;
3719}
Jamie Madillc29968b2016-01-20 11:17:23 -05003720
Jamie Madill5b772312018-03-08 20:28:32 -05003721bool ValidateDrawBuffersBase(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05003722{
3723 // INVALID_VALUE is generated if n is negative or greater than value of MAX_DRAW_BUFFERS
Brandon Jonesafa75152017-07-21 13:11:29 -07003724 if (n < 0)
Jamie Madillc29968b2016-01-20 11:17:23 -05003725 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003726 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
3727 return false;
3728 }
3729 if (static_cast<GLuint>(n) > context->getCaps().maxDrawBuffers)
3730 {
3731 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxDrawBuffer);
Jamie Madillc29968b2016-01-20 11:17:23 -05003732 return false;
3733 }
3734
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003735 ASSERT(context->getGLState().getDrawFramebuffer());
3736 GLuint frameBufferId = context->getGLState().getDrawFramebuffer()->id();
Jamie Madillc29968b2016-01-20 11:17:23 -05003737 GLuint maxColorAttachment = GL_COLOR_ATTACHMENT0_EXT + context->getCaps().maxColorAttachments;
3738
3739 // This should come first before the check for the default frame buffer
3740 // because when we switch to ES3.1+, invalid enums will return INVALID_ENUM
3741 // rather than INVALID_OPERATION
3742 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
3743 {
3744 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
3745
3746 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != GL_BACK &&
Olli Etuaho84c9f592016-03-09 14:37:25 +02003747 (bufs[colorAttachment] < GL_COLOR_ATTACHMENT0 ||
3748 bufs[colorAttachment] > GL_COLOR_ATTACHMENT31))
Jamie Madillc29968b2016-01-20 11:17:23 -05003749 {
3750 // Value in bufs is not NONE, BACK, or GL_COLOR_ATTACHMENTi
Olli Etuaho84c9f592016-03-09 14:37:25 +02003751 // The 3.0.4 spec says to generate GL_INVALID_OPERATION here, but this
3752 // was changed to GL_INVALID_ENUM in 3.1, which dEQP also expects.
3753 // 3.1 is still a bit ambiguous about the error, but future specs are
3754 // expected to clarify that GL_INVALID_ENUM is the correct error.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003755 context->handleError(InvalidEnum() << "Invalid buffer value");
Olli Etuaho84c9f592016-03-09 14:37:25 +02003756 return false;
3757 }
3758 else if (bufs[colorAttachment] >= maxColorAttachment)
3759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003760 context->handleError(InvalidOperation()
3761 << "Buffer value is greater than MAX_DRAW_BUFFERS");
Jamie Madillc29968b2016-01-20 11:17:23 -05003762 return false;
3763 }
3764 else if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment &&
3765 frameBufferId != 0)
3766 {
3767 // INVALID_OPERATION-GL is bound to buffer and ith argument
3768 // is not COLOR_ATTACHMENTi or NONE
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003769 context->handleError(InvalidOperation()
3770 << "Ith value does not match COLOR_ATTACHMENTi or NONE");
Jamie Madillc29968b2016-01-20 11:17:23 -05003771 return false;
3772 }
3773 }
3774
3775 // INVALID_OPERATION is generated if GL is bound to the default framebuffer
3776 // and n is not 1 or bufs is bound to value other than BACK and NONE
3777 if (frameBufferId == 0)
3778 {
3779 if (n != 1)
3780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003781 context->handleError(InvalidOperation()
3782 << "n must be 1 when GL is bound to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003783 return false;
3784 }
3785
3786 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
3787 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003788 context->handleError(
3789 InvalidOperation()
3790 << "Only NONE or BACK are valid values when drawing to the default framebuffer");
Jamie Madillc29968b2016-01-20 11:17:23 -05003791 return false;
3792 }
3793 }
3794
3795 return true;
3796}
3797
Geoff Lang496c02d2016-10-20 11:38:11 -07003798bool ValidateGetBufferPointervBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003799 BufferBinding target,
Geoff Lang496c02d2016-10-20 11:38:11 -07003800 GLenum pname,
3801 GLsizei *length,
3802 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003803{
Geoff Lang496c02d2016-10-20 11:38:11 -07003804 if (length)
3805 {
3806 *length = 0;
3807 }
3808
3809 if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapBuffer)
3810 {
3811 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003812 InvalidOperation()
3813 << "Context does not support OpenGL ES 3.0 or GL_OES_mapbuffer is not enabled.");
Geoff Lang496c02d2016-10-20 11:38:11 -07003814 return false;
3815 }
3816
Corentin Walleze4477002017-12-01 14:39:58 -05003817 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003818 {
Corentin Wallez336129f2017-10-17 15:55:40 -04003819 context->handleError(InvalidEnum() << "Buffer target not valid");
Olli Etuaho4f667482016-03-30 15:56:35 +03003820 return false;
3821 }
3822
Geoff Lang496c02d2016-10-20 11:38:11 -07003823 switch (pname)
Olli Etuaho4f667482016-03-30 15:56:35 +03003824 {
Geoff Lang496c02d2016-10-20 11:38:11 -07003825 case GL_BUFFER_MAP_POINTER:
3826 break;
Olli Etuaho4f667482016-03-30 15:56:35 +03003827
Geoff Lang496c02d2016-10-20 11:38:11 -07003828 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003829 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang496c02d2016-10-20 11:38:11 -07003830 return false;
3831 }
Olli Etuaho4f667482016-03-30 15:56:35 +03003832
3833 // GLES 3.0 section 2.10.1: "Attempts to attempts to modify or query buffer object state for a
3834 // target bound to zero generate an INVALID_OPERATION error."
3835 // GLES 3.1 section 6.6 explicitly specifies this error.
Geoff Lang496c02d2016-10-20 11:38:11 -07003836 if (context->getGLState().getTargetBuffer(target) == nullptr)
Olli Etuaho4f667482016-03-30 15:56:35 +03003837 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003838 context->handleError(InvalidOperation()
3839 << "Can not get pointer for reserved buffer name zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003840 return false;
3841 }
3842
Geoff Lang496c02d2016-10-20 11:38:11 -07003843 if (length)
3844 {
3845 *length = 1;
3846 }
3847
Olli Etuaho4f667482016-03-30 15:56:35 +03003848 return true;
3849}
3850
Corentin Wallez336129f2017-10-17 15:55:40 -04003851bool ValidateUnmapBufferBase(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003852{
Corentin Walleze4477002017-12-01 14:39:58 -05003853 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003854 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003855 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003856 return false;
3857 }
3858
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003859 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003860
3861 if (buffer == nullptr || !buffer->isMapped())
3862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003863 context->handleError(InvalidOperation() << "Buffer not mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003864 return false;
3865 }
3866
3867 return true;
3868}
3869
3870bool ValidateMapBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003871 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003872 GLintptr offset,
3873 GLsizeiptr length,
3874 GLbitfield access)
3875{
Corentin Walleze4477002017-12-01 14:39:58 -05003876 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003877 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003878 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003879 return false;
3880 }
3881
Brandon Jones6cad5662017-06-14 13:25:13 -07003882 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003884 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
3885 return false;
3886 }
3887
3888 if (length < 0)
3889 {
3890 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003891 return false;
3892 }
3893
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003894 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003895
3896 if (!buffer)
3897 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003898 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003899 return false;
3900 }
3901
3902 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04003903 CheckedNumeric<size_t> checkedOffset(offset);
3904 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03003905
Jamie Madille2e406c2016-06-02 13:04:10 -04003906 if (!checkedSize.IsValid() || checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getSize()))
Olli Etuaho4f667482016-03-30 15:56:35 +03003907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "Mapped range does not fit into buffer dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003909 return false;
3910 }
3911
3912 // Check for invalid bits in the mask
3913 GLbitfield allAccessBits = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT |
3914 GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT |
3915 GL_MAP_UNSYNCHRONIZED_BIT;
3916
3917 if (access & ~(allAccessBits))
3918 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003919 context->handleError(InvalidValue()
3920 << "Invalid access bits: 0x" << std::hex << std::uppercase << access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003921 return false;
3922 }
3923
3924 if (length == 0)
3925 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003926 context->handleError(InvalidOperation() << "Buffer mapping length is zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003927 return false;
3928 }
3929
3930 if (buffer->isMapped())
3931 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003932 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003933 return false;
3934 }
3935
3936 // Check for invalid bit combinations
3937 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0)
3938 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003939 context->handleError(InvalidOperation()
3940 << "Need to map buffer for either reading or writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003941 return false;
3942 }
3943
3944 GLbitfield writeOnlyBits =
3945 GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT;
3946
3947 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0)
3948 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003949 context->handleError(InvalidOperation()
3950 << "Invalid access bits when mapping buffer for reading: 0x"
3951 << std::hex << std::uppercase << access);
Olli Etuaho4f667482016-03-30 15:56:35 +03003952 return false;
3953 }
3954
3955 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0)
3956 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003957 context->handleError(
3958 InvalidOperation()
3959 << "The explicit flushing bit may only be set if the buffer is mapped for writing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003960 return false;
3961 }
Geoff Lang79f71042017-08-14 16:43:43 -04003962
3963 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003964}
3965
3966bool ValidateFlushMappedBufferRangeBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003967 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003968 GLintptr offset,
3969 GLsizeiptr length)
3970{
Brandon Jones6cad5662017-06-14 13:25:13 -07003971 if (offset < 0)
Olli Etuaho4f667482016-03-30 15:56:35 +03003972 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003973 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
3974 return false;
3975 }
3976
3977 if (length < 0)
3978 {
3979 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeLength);
Olli Etuaho4f667482016-03-30 15:56:35 +03003980 return false;
3981 }
3982
Corentin Walleze4477002017-12-01 14:39:58 -05003983 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003986 return false;
3987 }
3988
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003989 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003990
3991 if (buffer == nullptr)
3992 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003993 context->handleError(InvalidOperation() << "Attempted to flush buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003994 return false;
3995 }
3996
3997 if (!buffer->isMapped() || (buffer->getAccessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0)
3998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003999 context->handleError(InvalidOperation()
4000 << "Attempted to flush a buffer not mapped for explicit flushing.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004001 return false;
4002 }
4003
4004 // Check for buffer overflow
Jamie Madille2e406c2016-06-02 13:04:10 -04004005 CheckedNumeric<size_t> checkedOffset(offset);
4006 auto checkedSize = checkedOffset + length;
Olli Etuaho4f667482016-03-30 15:56:35 +03004007
Jamie Madille2e406c2016-06-02 13:04:10 -04004008 if (!checkedSize.IsValid() ||
4009 checkedSize.ValueOrDie() > static_cast<size_t>(buffer->getMapLength()))
Olli Etuaho4f667482016-03-30 15:56:35 +03004010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004011 context->handleError(InvalidValue()
4012 << "Flushed range does not fit into buffer mapping dimensions.");
Olli Etuaho4f667482016-03-30 15:56:35 +03004013 return false;
4014 }
4015
4016 return true;
4017}
4018
Olli Etuaho41997e72016-03-10 13:38:39 +02004019bool ValidateGenOrDelete(Context *context, GLint n)
4020{
4021 if (n < 0)
4022 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004023 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Olli Etuaho41997e72016-03-10 13:38:39 +02004024 return false;
4025 }
4026 return true;
4027}
4028
Jamie Madill5b772312018-03-08 20:28:32 -05004029bool ValidateRobustEntryPoint(Context *context, GLsizei bufSize)
Geoff Langff5b2d52016-09-07 11:32:23 -04004030{
4031 if (!context->getExtensions().robustClientMemory)
4032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004033 context->handleError(InvalidOperation()
4034 << "GL_ANGLE_robust_client_memory is not available.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004035 return false;
4036 }
4037
4038 if (bufSize < 0)
4039 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004040 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Langff5b2d52016-09-07 11:32:23 -04004041 return false;
4042 }
4043
4044 return true;
4045}
4046
Jamie Madill5b772312018-03-08 20:28:32 -05004047bool ValidateRobustBufferSize(Context *context, GLsizei bufSize, GLsizei numParams)
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004048{
4049 if (bufSize < numParams)
4050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004051 context->handleError(InvalidOperation() << numParams << " parameters are required but "
4052 << bufSize << " were provided.");
Geoff Lang2e43dbb2016-10-14 12:27:35 -04004053 return false;
4054 }
4055
4056 return true;
4057}
4058
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004059bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04004060 GLenum target,
4061 GLenum attachment,
4062 GLenum pname,
4063 GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004064{
Geoff Lange8afa902017-09-27 15:00:43 -04004065 if (!ValidFramebufferTarget(context, target))
Geoff Langff5b2d52016-09-07 11:32:23 -04004066 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004067 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004068 return false;
4069 }
4070
4071 int clientVersion = context->getClientMajorVersion();
4072
4073 switch (pname)
4074 {
4075 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4076 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4077 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4078 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4079 break;
4080
Martin Radeve5285d22017-07-14 16:23:53 +03004081 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_ANGLE:
4082 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_MULTIVIEW_LAYOUT_ANGLE:
4083 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_ANGLE:
4084 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE:
4085 if (clientVersion < 3 || !context->getExtensions().multiview)
4086 {
4087 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
4088 return false;
4089 }
4090 break;
4091
Geoff Langff5b2d52016-09-07 11:32:23 -04004092 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
4093 if (clientVersion < 3 && !context->getExtensions().sRGB)
4094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004095 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004096 return false;
4097 }
4098 break;
4099
4100 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
4101 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
4102 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
4103 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
4104 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
4105 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
4106 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4107 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4108 if (clientVersion < 3)
4109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004110 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004111 return false;
4112 }
4113 break;
4114
Jiawei Shaoa8802472018-05-28 11:17:47 +08004115 case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
4116 if (!context->getExtensions().geometryShader)
4117 {
4118 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
4119 return false;
4120 }
4121 break;
4122
Geoff Langff5b2d52016-09-07 11:32:23 -04004123 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidEnum());
Geoff Langff5b2d52016-09-07 11:32:23 -04004125 return false;
4126 }
4127
4128 // Determine if the attachment is a valid enum
4129 switch (attachment)
4130 {
4131 case GL_BACK:
Geoff Langff5b2d52016-09-07 11:32:23 -04004132 case GL_DEPTH:
4133 case GL_STENCIL:
Geoff Langff5b2d52016-09-07 11:32:23 -04004134 if (clientVersion < 3)
4135 {
Geoff Langfa125c92017-10-24 13:01:46 -04004136 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004137 return false;
4138 }
4139 break;
4140
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004141 case GL_DEPTH_STENCIL_ATTACHMENT:
4142 if (clientVersion < 3 && !context->isWebGL1())
4143 {
4144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
4145 return false;
4146 }
4147 break;
4148
Geoff Langfa125c92017-10-24 13:01:46 -04004149 case GL_COLOR_ATTACHMENT0:
Geoff Langff5b2d52016-09-07 11:32:23 -04004150 case GL_DEPTH_ATTACHMENT:
4151 case GL_STENCIL_ATTACHMENT:
4152 break;
4153
4154 default:
Geoff Langfa125c92017-10-24 13:01:46 -04004155 if ((clientVersion < 3 && !context->getExtensions().drawBuffers) ||
4156 attachment < GL_COLOR_ATTACHMENT0_EXT ||
Geoff Langff5b2d52016-09-07 11:32:23 -04004157 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getCaps().maxColorAttachments)
4158 {
Geoff Langfa125c92017-10-24 13:01:46 -04004159 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004160 return false;
4161 }
4162 break;
4163 }
4164
4165 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
4166 ASSERT(framebuffer);
4167
4168 if (framebuffer->id() == 0)
4169 {
4170 if (clientVersion < 3)
4171 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004172 ANGLE_VALIDATION_ERR(context, InvalidOperation(), DefaultFramebufferTarget);
Geoff Langff5b2d52016-09-07 11:32:23 -04004173 return false;
4174 }
4175
4176 switch (attachment)
4177 {
4178 case GL_BACK:
4179 case GL_DEPTH:
4180 case GL_STENCIL:
4181 break;
4182
4183 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004184 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004185 return false;
4186 }
4187 }
4188 else
4189 {
4190 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
4191 {
4192 // Valid attachment query
4193 }
4194 else
4195 {
4196 switch (attachment)
4197 {
4198 case GL_DEPTH_ATTACHMENT:
4199 case GL_STENCIL_ATTACHMENT:
4200 break;
4201
4202 case GL_DEPTH_STENCIL_ATTACHMENT:
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004203 if (!framebuffer->hasValidDepthStencil() && !context->isWebGL1())
Geoff Langff5b2d52016-09-07 11:32:23 -04004204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004205 context->handleError(InvalidOperation());
Geoff Langff5b2d52016-09-07 11:32:23 -04004206 return false;
4207 }
4208 break;
4209
4210 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004211 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004212 return false;
4213 }
4214 }
4215 }
4216
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004217 const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004218 if (attachmentObject)
4219 {
4220 ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
4221 attachmentObject->type() == GL_TEXTURE ||
4222 attachmentObject->type() == GL_FRAMEBUFFER_DEFAULT);
4223
4224 switch (pname)
4225 {
4226 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4227 if (attachmentObject->type() != GL_RENDERBUFFER &&
4228 attachmentObject->type() != GL_TEXTURE)
4229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004231 return false;
4232 }
4233 break;
4234
4235 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
4236 if (attachmentObject->type() != GL_TEXTURE)
4237 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004238 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004239 return false;
4240 }
4241 break;
4242
4243 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
4244 if (attachmentObject->type() != GL_TEXTURE)
4245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004247 return false;
4248 }
4249 break;
4250
4251 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
4252 if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
4253 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004254 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004255 return false;
4256 }
4257 break;
4258
4259 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
4260 if (attachmentObject->type() != GL_TEXTURE)
4261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), FramebufferIncompleteAttachment);
Geoff Langff5b2d52016-09-07 11:32:23 -04004263 return false;
4264 }
4265 break;
4266
4267 default:
4268 break;
4269 }
4270 }
4271 else
4272 {
4273 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
4274 // is NONE, then querying any other pname will generate INVALID_ENUM.
4275
4276 // ES 3.0.2 spec pg 235 states that if the attachment type is none,
4277 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
4278 // INVALID_OPERATION for all other pnames
4279
4280 switch (pname)
4281 {
4282 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
4283 break;
4284
4285 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
4286 if (clientVersion < 3)
4287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004288 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004289 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004290 return false;
4291 }
4292 break;
4293
4294 default:
4295 if (clientVersion < 3)
4296 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004297 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004298 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004299 return false;
4300 }
4301 else
4302 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004303 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
Bryan Bernhart (Intel Americas Inc)491b0d62017-11-10 12:48:22 -08004304 InvalidFramebufferAttachmentParameter);
Geoff Langff5b2d52016-09-07 11:32:23 -04004305 return false;
4306 }
4307 }
4308 }
4309
Martin Radeve5285d22017-07-14 16:23:53 +03004310 if (numParams)
4311 {
4312 if (pname == GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_VIEWPORT_OFFSETS_ANGLE)
4313 {
4314 // Only when the viewport offsets are queried we can have a varying number of output
4315 // parameters.
4316 const int numViews = attachmentObject ? attachmentObject->getNumViews() : 1;
4317 *numParams = numViews * 2;
4318 }
4319 else
4320 {
4321 // For all other queries we can have only one output parameter.
4322 *numParams = 1;
4323 }
4324 }
4325
Geoff Langff5b2d52016-09-07 11:32:23 -04004326 return true;
4327}
4328
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08004329bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
Geoff Langff5b2d52016-09-07 11:32:23 -04004330 GLenum target,
4331 GLenum attachment,
4332 GLenum pname,
4333 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004334 GLsizei *length,
4335 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004336{
4337 if (!ValidateRobustEntryPoint(context, bufSize))
4338 {
4339 return false;
4340 }
4341
Brandon Jonesd1049182018-03-28 10:02:20 -07004342 GLsizei numParams = 0;
Jamie Madillbe849e42017-05-02 15:49:00 -04004343 if (!ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004344 &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004345 {
4346 return false;
4347 }
4348
Brandon Jonesd1049182018-03-28 10:02:20 -07004349 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004350 {
4351 return false;
4352 }
4353
Brandon Jonesd1049182018-03-28 10:02:20 -07004354 SetRobustLengthParam(length, numParams);
4355
Geoff Langff5b2d52016-09-07 11:32:23 -04004356 return true;
4357}
4358
Jamie Madill5b772312018-03-08 20:28:32 -05004359bool ValidateGetBufferParameterivRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004360 BufferBinding target,
Geoff Langff5b2d52016-09-07 11:32:23 -04004361 GLenum pname,
4362 GLsizei bufSize,
Geoff Langebebe1c2016-10-14 12:01:31 -04004363 GLsizei *length,
4364 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004365{
4366 if (!ValidateRobustEntryPoint(context, bufSize))
4367 {
4368 return false;
4369 }
4370
Brandon Jonesd1049182018-03-28 10:02:20 -07004371 GLsizei numParams = 0;
4372
4373 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004374 {
4375 return false;
4376 }
4377
Brandon Jonesd1049182018-03-28 10:02:20 -07004378 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004379 {
4380 return false;
4381 }
4382
Brandon Jonesd1049182018-03-28 10:02:20 -07004383 SetRobustLengthParam(length, numParams);
Geoff Langebebe1c2016-10-14 12:01:31 -04004384 return true;
4385}
4386
Jamie Madill5b772312018-03-08 20:28:32 -05004387bool ValidateGetBufferParameteri64vRobustANGLE(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004388 BufferBinding target,
Geoff Langebebe1c2016-10-14 12:01:31 -04004389 GLenum pname,
4390 GLsizei bufSize,
4391 GLsizei *length,
4392 GLint64 *params)
4393{
Brandon Jonesd1049182018-03-28 10:02:20 -07004394 GLsizei numParams = 0;
4395
Geoff Langebebe1c2016-10-14 12:01:31 -04004396 if (!ValidateRobustEntryPoint(context, bufSize))
4397 {
4398 return false;
4399 }
4400
Brandon Jonesd1049182018-03-28 10:02:20 -07004401 if (!ValidateGetBufferParameterBase(context, target, pname, false, &numParams))
Geoff Langebebe1c2016-10-14 12:01:31 -04004402 {
4403 return false;
4404 }
4405
Brandon Jonesd1049182018-03-28 10:02:20 -07004406 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004407 {
4408 return false;
4409 }
4410
Brandon Jonesd1049182018-03-28 10:02:20 -07004411 SetRobustLengthParam(length, numParams);
4412
Geoff Langff5b2d52016-09-07 11:32:23 -04004413 return true;
4414}
4415
Jamie Madill5b772312018-03-08 20:28:32 -05004416bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GLsizei *numParams)
Geoff Langff5b2d52016-09-07 11:32:23 -04004417{
4418 // Currently, all GetProgramiv queries return 1 parameter
Yunchao He33151a52017-04-13 09:58:17 +08004419 if (numParams)
4420 {
4421 *numParams = 1;
4422 }
Geoff Langff5b2d52016-09-07 11:32:23 -04004423
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004424 // Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
4425 Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
4426 ? GetValidProgramNoResolve(context, program)
4427 : GetValidProgram(context, program);
Geoff Langff5b2d52016-09-07 11:32:23 -04004428 if (!programObject)
4429 {
4430 return false;
4431 }
4432
4433 switch (pname)
4434 {
4435 case GL_DELETE_STATUS:
4436 case GL_LINK_STATUS:
4437 case GL_VALIDATE_STATUS:
4438 case GL_INFO_LOG_LENGTH:
4439 case GL_ATTACHED_SHADERS:
4440 case GL_ACTIVE_ATTRIBUTES:
4441 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
4442 case GL_ACTIVE_UNIFORMS:
4443 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
4444 break;
4445
4446 case GL_PROGRAM_BINARY_LENGTH:
4447 if (context->getClientMajorVersion() < 3 && !context->getExtensions().getProgramBinary)
4448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004449 context->handleError(InvalidEnum() << "Querying GL_PROGRAM_BINARY_LENGTH "
4450 "requires GL_OES_get_program_binary or "
4451 "ES 3.0.");
Geoff Langff5b2d52016-09-07 11:32:23 -04004452 return false;
4453 }
4454 break;
4455
4456 case GL_ACTIVE_UNIFORM_BLOCKS:
4457 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
4458 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
4459 case GL_TRANSFORM_FEEDBACK_VARYINGS:
4460 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
4461 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
4462 if (context->getClientMajorVersion() < 3)
4463 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004464 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Geoff Langff5b2d52016-09-07 11:32:23 -04004465 return false;
4466 }
4467 break;
4468
Yunchao He61afff12017-03-14 15:34:03 +08004469 case GL_PROGRAM_SEPARABLE:
jchen1058f67be2017-10-27 08:59:27 +08004470 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
Yunchao He61afff12017-03-14 15:34:03 +08004471 if (context->getClientVersion() < Version(3, 1))
4472 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Yunchao He61afff12017-03-14 15:34:03 +08004474 return false;
4475 }
4476 break;
4477
Jiawei Shao6ae51612018-02-23 14:03:25 +08004478 case GL_COMPUTE_WORK_GROUP_SIZE:
4479 if (context->getClientVersion() < Version(3, 1))
4480 {
4481 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
4482 return false;
4483 }
4484
4485 // [OpenGL ES 3.1] Chapter 7.12 Page 122
4486 // An INVALID_OPERATION error is generated if COMPUTE_WORK_GROUP_SIZE is queried for a
4487 // program which has not been linked successfully, or which does not contain objects to
4488 // form a compute shader.
4489 if (!programObject->isLinked())
4490 {
4491 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
4492 return false;
4493 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004494 if (!programObject->hasLinkedShaderStage(ShaderType::Compute))
Jiawei Shao6ae51612018-02-23 14:03:25 +08004495 {
4496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveComputeShaderStage);
4497 return false;
4498 }
4499 break;
4500
Jiawei Shao447bfac2018-03-14 14:23:40 +08004501 case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
4502 case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
4503 case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
4504 case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
4505 if (!context->getExtensions().geometryShader)
4506 {
4507 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GeometryShaderExtensionNotEnabled);
4508 return false;
4509 }
4510
4511 // [EXT_geometry_shader] Chapter 7.12
4512 // An INVALID_OPERATION error is generated if GEOMETRY_LINKED_VERTICES_OUT_EXT,
4513 // GEOMETRY_LINKED_INPUT_TYPE_EXT, GEOMETRY_LINKED_OUTPUT_TYPE_EXT, or
4514 // GEOMETRY_SHADER_INVOCATIONS_EXT are queried for a program which has not been linked
4515 // successfully, or which does not contain objects to form a geometry shader.
4516 if (!programObject->isLinked())
4517 {
4518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
4519 return false;
4520 }
Jiawei Shao385b3e02018-03-21 09:43:28 +08004521 if (!programObject->hasLinkedShaderStage(ShaderType::Geometry))
Jiawei Shao447bfac2018-03-14 14:23:40 +08004522 {
4523 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveGeometryShaderStage);
4524 return false;
4525 }
4526 break;
4527
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004528 case GL_COMPLETION_STATUS_KHR:
4529 if (!context->getExtensions().parallelShaderCompile)
4530 {
4531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
4532 return false;
4533 }
4534 break;
4535
Geoff Langff5b2d52016-09-07 11:32:23 -04004536 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Langff5b2d52016-09-07 11:32:23 -04004538 return false;
4539 }
4540
4541 return true;
4542}
4543
4544bool ValidateGetProgramivRobustANGLE(Context *context,
4545 GLuint program,
4546 GLenum pname,
4547 GLsizei bufSize,
Brandon Jonesd1049182018-03-28 10:02:20 -07004548 GLsizei *length,
4549 GLint *params)
Geoff Langff5b2d52016-09-07 11:32:23 -04004550{
4551 if (!ValidateRobustEntryPoint(context, bufSize))
4552 {
4553 return false;
4554 }
4555
Brandon Jonesd1049182018-03-28 10:02:20 -07004556 GLsizei numParams = 0;
4557
4558 if (!ValidateGetProgramivBase(context, program, pname, &numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004559 {
4560 return false;
4561 }
4562
Brandon Jonesd1049182018-03-28 10:02:20 -07004563 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langff5b2d52016-09-07 11:32:23 -04004564 {
4565 return false;
4566 }
4567
Brandon Jonesd1049182018-03-28 10:02:20 -07004568 SetRobustLengthParam(length, numParams);
4569
Geoff Langff5b2d52016-09-07 11:32:23 -04004570 return true;
4571}
4572
Geoff Lang740d9022016-10-07 11:20:52 -04004573bool ValidateGetRenderbufferParameterivRobustANGLE(Context *context,
4574 GLenum target,
4575 GLenum pname,
4576 GLsizei bufSize,
4577 GLsizei *length,
4578 GLint *params)
4579{
4580 if (!ValidateRobustEntryPoint(context, bufSize))
4581 {
4582 return false;
4583 }
4584
Brandon Jonesd1049182018-03-28 10:02:20 -07004585 GLsizei numParams = 0;
4586
4587 if (!ValidateGetRenderbufferParameterivBase(context, target, pname, &numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004588 {
4589 return false;
4590 }
4591
Brandon Jonesd1049182018-03-28 10:02:20 -07004592 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang740d9022016-10-07 11:20:52 -04004593 {
4594 return false;
4595 }
4596
Brandon Jonesd1049182018-03-28 10:02:20 -07004597 SetRobustLengthParam(length, numParams);
4598
Geoff Lang740d9022016-10-07 11:20:52 -04004599 return true;
4600}
4601
Geoff Langd7d0ed32016-10-07 11:33:51 -04004602bool ValidateGetShaderivRobustANGLE(Context *context,
4603 GLuint shader,
4604 GLenum pname,
4605 GLsizei bufSize,
4606 GLsizei *length,
4607 GLint *params)
4608{
4609 if (!ValidateRobustEntryPoint(context, bufSize))
4610 {
4611 return false;
4612 }
4613
Brandon Jonesd1049182018-03-28 10:02:20 -07004614 GLsizei numParams = 0;
4615
4616 if (!ValidateGetShaderivBase(context, shader, pname, &numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004617 {
4618 return false;
4619 }
4620
Brandon Jonesd1049182018-03-28 10:02:20 -07004621 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langd7d0ed32016-10-07 11:33:51 -04004622 {
4623 return false;
4624 }
4625
Brandon Jonesd1049182018-03-28 10:02:20 -07004626 SetRobustLengthParam(length, numParams);
4627
Geoff Langd7d0ed32016-10-07 11:33:51 -04004628 return true;
4629}
4630
Geoff Langc1984ed2016-10-07 12:41:00 -04004631bool ValidateGetTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004632 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004633 GLenum pname,
4634 GLsizei bufSize,
4635 GLsizei *length,
4636 GLfloat *params)
4637{
4638 if (!ValidateRobustEntryPoint(context, bufSize))
4639 {
4640 return false;
4641 }
4642
Brandon Jonesd1049182018-03-28 10:02:20 -07004643 GLsizei numParams = 0;
4644
4645 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004646 {
4647 return false;
4648 }
4649
Brandon Jonesd1049182018-03-28 10:02:20 -07004650 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004651 {
4652 return false;
4653 }
4654
Brandon Jonesd1049182018-03-28 10:02:20 -07004655 SetRobustLengthParam(length, numParams);
4656
Geoff Langc1984ed2016-10-07 12:41:00 -04004657 return true;
4658}
4659
Geoff Langc1984ed2016-10-07 12:41:00 -04004660bool ValidateGetTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004661 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004662 GLenum pname,
4663 GLsizei bufSize,
4664 GLsizei *length,
4665 GLint *params)
4666{
Brandon Jonesd1049182018-03-28 10:02:20 -07004667
Geoff Langc1984ed2016-10-07 12:41:00 -04004668 if (!ValidateRobustEntryPoint(context, bufSize))
4669 {
4670 return false;
4671 }
Brandon Jonesd1049182018-03-28 10:02:20 -07004672 GLsizei numParams = 0;
4673 if (!ValidateGetTexParameterBase(context, target, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004674 {
4675 return false;
4676 }
4677
Brandon Jonesd1049182018-03-28 10:02:20 -07004678 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004679 {
4680 return false;
4681 }
4682
Brandon Jonesd1049182018-03-28 10:02:20 -07004683 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004684 return true;
4685}
4686
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004687bool ValidateGetTexParameterIivRobustANGLE(Context *context,
4688 TextureType target,
4689 GLenum pname,
4690 GLsizei bufSize,
4691 GLsizei *length,
4692 GLint *params)
4693{
4694 UNIMPLEMENTED();
4695 return false;
4696}
4697
4698bool ValidateGetTexParameterIuivRobustANGLE(Context *context,
4699 TextureType target,
4700 GLenum pname,
4701 GLsizei bufSize,
4702 GLsizei *length,
4703 GLuint *params)
4704{
4705 UNIMPLEMENTED();
4706 return false;
4707}
4708
Geoff Langc1984ed2016-10-07 12:41:00 -04004709bool ValidateTexParameterfvRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004710 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004711 GLenum pname,
4712 GLsizei bufSize,
4713 const GLfloat *params)
4714{
4715 if (!ValidateRobustEntryPoint(context, bufSize))
4716 {
4717 return false;
4718 }
4719
Till Rathmannb8543632018-10-02 19:46:14 +02004720 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004721}
4722
Geoff Langc1984ed2016-10-07 12:41:00 -04004723bool ValidateTexParameterivRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004724 TextureType target,
Geoff Langc1984ed2016-10-07 12:41:00 -04004725 GLenum pname,
4726 GLsizei bufSize,
4727 const GLint *params)
4728{
4729 if (!ValidateRobustEntryPoint(context, bufSize))
4730 {
4731 return false;
4732 }
4733
Till Rathmannb8543632018-10-02 19:46:14 +02004734 return ValidateTexParameterBase(context, target, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004735}
4736
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004737bool ValidateTexParameterIivRobustANGLE(Context *context,
4738 TextureType target,
4739 GLenum pname,
4740 GLsizei bufSize,
4741 const GLint *params)
4742{
4743 UNIMPLEMENTED();
4744 return false;
4745}
4746
4747bool ValidateTexParameterIuivRobustANGLE(Context *context,
4748 TextureType target,
4749 GLenum pname,
4750 GLsizei bufSize,
4751 const GLuint *params)
4752{
4753 UNIMPLEMENTED();
4754 return false;
4755}
4756
Geoff Langc1984ed2016-10-07 12:41:00 -04004757bool ValidateGetSamplerParameterfvRobustANGLE(Context *context,
4758 GLuint sampler,
4759 GLenum pname,
4760 GLuint bufSize,
4761 GLsizei *length,
4762 GLfloat *params)
4763{
4764 if (!ValidateRobustEntryPoint(context, bufSize))
4765 {
4766 return false;
4767 }
4768
Brandon Jonesd1049182018-03-28 10:02:20 -07004769 GLsizei numParams = 0;
4770
4771 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004772 {
4773 return false;
4774 }
4775
Brandon Jonesd1049182018-03-28 10:02:20 -07004776 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004777 {
4778 return false;
4779 }
4780
Brandon Jonesd1049182018-03-28 10:02:20 -07004781 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004782 return true;
4783}
4784
Geoff Langc1984ed2016-10-07 12:41:00 -04004785bool ValidateGetSamplerParameterivRobustANGLE(Context *context,
4786 GLuint sampler,
4787 GLenum pname,
Brandon Jonesd1049182018-03-28 10:02:20 -07004788 GLsizei bufSize,
Geoff Langc1984ed2016-10-07 12:41:00 -04004789 GLsizei *length,
4790 GLint *params)
4791{
4792 if (!ValidateRobustEntryPoint(context, bufSize))
4793 {
4794 return false;
4795 }
4796
Brandon Jonesd1049182018-03-28 10:02:20 -07004797 GLsizei numParams = 0;
4798
4799 if (!ValidateGetSamplerParameterBase(context, sampler, pname, &numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004800 {
4801 return false;
4802 }
4803
Brandon Jonesd1049182018-03-28 10:02:20 -07004804 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Langc1984ed2016-10-07 12:41:00 -04004805 {
4806 return false;
4807 }
4808
Brandon Jonesd1049182018-03-28 10:02:20 -07004809 SetRobustLengthParam(length, numParams);
Geoff Langc1984ed2016-10-07 12:41:00 -04004810 return true;
4811}
4812
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004813bool ValidateGetSamplerParameterIivRobustANGLE(Context *context,
4814 GLuint sampler,
4815 GLenum pname,
4816 GLsizei bufSize,
4817 GLsizei *length,
4818 GLint *params)
4819{
4820 UNIMPLEMENTED();
4821 return false;
4822}
4823
4824bool ValidateGetSamplerParameterIuivRobustANGLE(Context *context,
4825 GLuint sampler,
4826 GLenum pname,
4827 GLsizei bufSize,
4828 GLsizei *length,
4829 GLuint *params)
4830{
4831 UNIMPLEMENTED();
4832 return false;
4833}
4834
Geoff Langc1984ed2016-10-07 12:41:00 -04004835bool ValidateSamplerParameterfvRobustANGLE(Context *context,
4836 GLuint sampler,
4837 GLenum pname,
4838 GLsizei bufSize,
4839 const GLfloat *params)
4840{
4841 if (!ValidateRobustEntryPoint(context, bufSize))
4842 {
4843 return false;
4844 }
4845
Till Rathmannb8543632018-10-02 19:46:14 +02004846 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004847}
4848
Geoff Langc1984ed2016-10-07 12:41:00 -04004849bool ValidateSamplerParameterivRobustANGLE(Context *context,
4850 GLuint sampler,
4851 GLenum pname,
4852 GLsizei bufSize,
4853 const GLint *params)
4854{
4855 if (!ValidateRobustEntryPoint(context, bufSize))
4856 {
4857 return false;
4858 }
4859
Till Rathmannb8543632018-10-02 19:46:14 +02004860 return ValidateSamplerParameterBase(context, sampler, pname, bufSize, true, params);
Geoff Langc1984ed2016-10-07 12:41:00 -04004861}
4862
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07004863bool ValidateSamplerParameterIivRobustANGLE(Context *context,
4864 GLuint sampler,
4865 GLenum pname,
4866 GLsizei bufSize,
4867 const GLint *param)
4868{
4869 UNIMPLEMENTED();
4870 return false;
4871}
4872
4873bool ValidateSamplerParameterIuivRobustANGLE(Context *context,
4874 GLuint sampler,
4875 GLenum pname,
4876 GLsizei bufSize,
4877 const GLuint *param)
4878{
4879 UNIMPLEMENTED();
4880 return false;
4881}
4882
Geoff Lang0b031062016-10-13 14:30:04 -04004883bool ValidateGetVertexAttribfvRobustANGLE(Context *context,
4884 GLuint index,
4885 GLenum pname,
4886 GLsizei bufSize,
4887 GLsizei *length,
4888 GLfloat *params)
4889{
4890 if (!ValidateRobustEntryPoint(context, bufSize))
4891 {
4892 return false;
4893 }
4894
Brandon Jonesd1049182018-03-28 10:02:20 -07004895 GLsizei writeLength = 0;
4896
4897 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004898 {
4899 return false;
4900 }
4901
Brandon Jonesd1049182018-03-28 10:02:20 -07004902 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004903 {
4904 return false;
4905 }
4906
Brandon Jonesd1049182018-03-28 10:02:20 -07004907 SetRobustLengthParam(length, writeLength);
Geoff Lang0b031062016-10-13 14:30:04 -04004908 return true;
4909}
4910
Geoff Lang0b031062016-10-13 14:30:04 -04004911bool ValidateGetVertexAttribivRobustANGLE(Context *context,
4912 GLuint index,
4913 GLenum pname,
4914 GLsizei bufSize,
4915 GLsizei *length,
4916 GLint *params)
4917{
4918 if (!ValidateRobustEntryPoint(context, bufSize))
4919 {
4920 return false;
4921 }
4922
Brandon Jonesd1049182018-03-28 10:02:20 -07004923 GLsizei writeLength = 0;
4924
4925 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004926 {
4927 return false;
4928 }
4929
Brandon Jonesd1049182018-03-28 10:02:20 -07004930 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004931 {
4932 return false;
4933 }
4934
Brandon Jonesd1049182018-03-28 10:02:20 -07004935 SetRobustLengthParam(length, writeLength);
4936
Geoff Lang0b031062016-10-13 14:30:04 -04004937 return true;
4938}
4939
Geoff Lang0b031062016-10-13 14:30:04 -04004940bool ValidateGetVertexAttribPointervRobustANGLE(Context *context,
4941 GLuint index,
4942 GLenum pname,
4943 GLsizei bufSize,
4944 GLsizei *length,
4945 void **pointer)
4946{
4947 if (!ValidateRobustEntryPoint(context, bufSize))
4948 {
4949 return false;
4950 }
4951
Brandon Jonesd1049182018-03-28 10:02:20 -07004952 GLsizei writeLength = 0;
4953
4954 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, true, false))
Geoff Lang0b031062016-10-13 14:30:04 -04004955 {
4956 return false;
4957 }
4958
Brandon Jonesd1049182018-03-28 10:02:20 -07004959 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004960 {
4961 return false;
4962 }
4963
Brandon Jonesd1049182018-03-28 10:02:20 -07004964 SetRobustLengthParam(length, writeLength);
4965
Geoff Lang0b031062016-10-13 14:30:04 -04004966 return true;
4967}
4968
Geoff Lang0b031062016-10-13 14:30:04 -04004969bool ValidateGetVertexAttribIivRobustANGLE(Context *context,
4970 GLuint index,
4971 GLenum pname,
4972 GLsizei bufSize,
4973 GLsizei *length,
4974 GLint *params)
4975{
4976 if (!ValidateRobustEntryPoint(context, bufSize))
4977 {
4978 return false;
4979 }
4980
Brandon Jonesd1049182018-03-28 10:02:20 -07004981 GLsizei writeLength = 0;
4982
4983 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04004984 {
4985 return false;
4986 }
4987
Brandon Jonesd1049182018-03-28 10:02:20 -07004988 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04004989 {
4990 return false;
4991 }
4992
Brandon Jonesd1049182018-03-28 10:02:20 -07004993 SetRobustLengthParam(length, writeLength);
4994
Geoff Lang0b031062016-10-13 14:30:04 -04004995 return true;
4996}
4997
Geoff Lang0b031062016-10-13 14:30:04 -04004998bool ValidateGetVertexAttribIuivRobustANGLE(Context *context,
4999 GLuint index,
5000 GLenum pname,
5001 GLsizei bufSize,
5002 GLsizei *length,
5003 GLuint *params)
5004{
5005 if (!ValidateRobustEntryPoint(context, bufSize))
5006 {
5007 return false;
5008 }
5009
Brandon Jonesd1049182018-03-28 10:02:20 -07005010 GLsizei writeLength = 0;
5011
5012 if (!ValidateGetVertexAttribBase(context, index, pname, &writeLength, false, true))
Geoff Lang0b031062016-10-13 14:30:04 -04005013 {
5014 return false;
5015 }
5016
Brandon Jonesd1049182018-03-28 10:02:20 -07005017 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang0b031062016-10-13 14:30:04 -04005018 {
5019 return false;
5020 }
5021
Brandon Jonesd1049182018-03-28 10:02:20 -07005022 SetRobustLengthParam(length, writeLength);
5023
Geoff Lang0b031062016-10-13 14:30:04 -04005024 return true;
5025}
5026
Geoff Lang6899b872016-10-14 11:30:13 -04005027bool ValidateGetActiveUniformBlockivRobustANGLE(Context *context,
5028 GLuint program,
5029 GLuint uniformBlockIndex,
5030 GLenum pname,
5031 GLsizei bufSize,
5032 GLsizei *length,
5033 GLint *params)
5034{
5035 if (!ValidateRobustEntryPoint(context, bufSize))
5036 {
5037 return false;
5038 }
5039
Brandon Jonesd1049182018-03-28 10:02:20 -07005040 GLsizei writeLength = 0;
5041
5042 if (!ValidateGetActiveUniformBlockivBase(context, program, uniformBlockIndex, pname,
5043 &writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005044 {
5045 return false;
5046 }
5047
Brandon Jonesd1049182018-03-28 10:02:20 -07005048 if (!ValidateRobustBufferSize(context, bufSize, writeLength))
Geoff Lang6899b872016-10-14 11:30:13 -04005049 {
5050 return false;
5051 }
5052
Brandon Jonesd1049182018-03-28 10:02:20 -07005053 SetRobustLengthParam(length, writeLength);
5054
Geoff Lang6899b872016-10-14 11:30:13 -04005055 return true;
5056}
5057
Brandon Jones416aaf92018-04-10 08:10:16 -07005058bool ValidateGetInternalformativRobustANGLE(Context *context,
Geoff Lang0a9661f2016-10-20 10:59:20 -07005059 GLenum target,
5060 GLenum internalformat,
5061 GLenum pname,
5062 GLsizei bufSize,
5063 GLsizei *length,
5064 GLint *params)
5065{
5066 if (!ValidateRobustEntryPoint(context, bufSize))
5067 {
5068 return false;
5069 }
5070
Brandon Jonesd1049182018-03-28 10:02:20 -07005071 GLsizei numParams = 0;
5072
5073 if (!ValidateGetInternalFormativBase(context, target, internalformat, pname, bufSize,
5074 &numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005075 {
5076 return false;
5077 }
5078
Brandon Jonesd1049182018-03-28 10:02:20 -07005079 if (!ValidateRobustBufferSize(context, bufSize, numParams))
Geoff Lang0a9661f2016-10-20 10:59:20 -07005080 {
5081 return false;
5082 }
5083
Brandon Jonesd1049182018-03-28 10:02:20 -07005084 SetRobustLengthParam(length, numParams);
5085
Geoff Lang0a9661f2016-10-20 10:59:20 -07005086 return true;
5087}
5088
Jamie Madill5b772312018-03-08 20:28:32 -05005089bool ValidateVertexFormatBase(Context *context,
Shao80957d92017-02-20 21:25:59 +08005090 GLuint attribIndex,
5091 GLint size,
5092 GLenum type,
5093 GLboolean pureInteger)
5094{
5095 const Caps &caps = context->getCaps();
5096 if (attribIndex >= caps.maxVertexAttributes)
5097 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005098 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Shao80957d92017-02-20 21:25:59 +08005099 return false;
5100 }
5101
5102 if (size < 1 || size > 4)
5103 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005104 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidVertexAttrSize);
Geoff Lang8700a982017-06-13 10:15:13 -04005105 return false;
Shao80957d92017-02-20 21:25:59 +08005106 }
5107
5108 switch (type)
5109 {
5110 case GL_BYTE:
5111 case GL_UNSIGNED_BYTE:
5112 case GL_SHORT:
5113 case GL_UNSIGNED_SHORT:
5114 break;
5115
5116 case GL_INT:
5117 case GL_UNSIGNED_INT:
5118 if (context->getClientMajorVersion() < 3)
5119 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005120 context->handleError(InvalidEnum()
5121 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005122 return false;
5123 }
5124 break;
5125
5126 case GL_FIXED:
5127 case GL_FLOAT:
5128 if (pureInteger)
5129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005130 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005131 return false;
5132 }
5133 break;
5134
5135 case GL_HALF_FLOAT:
5136 if (context->getClientMajorVersion() < 3)
5137 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005138 context->handleError(InvalidEnum()
5139 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005140 return false;
5141 }
5142 if (pureInteger)
5143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005145 return false;
5146 }
5147 break;
5148
5149 case GL_INT_2_10_10_10_REV:
5150 case GL_UNSIGNED_INT_2_10_10_10_REV:
5151 if (context->getClientMajorVersion() < 3)
5152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005153 context->handleError(InvalidEnum()
5154 << "Vertex type not supported before OpenGL ES 3.0.");
Shao80957d92017-02-20 21:25:59 +08005155 return false;
5156 }
5157 if (pureInteger)
5158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005159 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTypePureInt);
Shao80957d92017-02-20 21:25:59 +08005160 return false;
5161 }
5162 if (size != 4)
5163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005164 context->handleError(InvalidOperation() << "Type is INT_2_10_10_10_REV or "
5165 "UNSIGNED_INT_2_10_10_10_REV and "
5166 "size is not 4.");
Shao80957d92017-02-20 21:25:59 +08005167 return false;
5168 }
5169 break;
5170
5171 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005172 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
Shao80957d92017-02-20 21:25:59 +08005173 return false;
5174 }
5175
5176 return true;
5177}
5178
Geoff Lang76e65652017-03-27 14:58:02 -04005179// Perform validation from WebGL 2 section 5.10 "Invalid Clears":
5180// In the WebGL 2 API, trying to perform a clear when there is a mismatch between the type of the
5181// specified clear value and the type of a buffer that is being cleared generates an
5182// INVALID_OPERATION error instead of producing undefined results
Jamie Madill5b772312018-03-08 20:28:32 -05005183bool ValidateWebGLFramebufferAttachmentClearType(Context *context,
Geoff Lang76e65652017-03-27 14:58:02 -04005184 GLint drawbuffer,
5185 const GLenum *validComponentTypes,
5186 size_t validComponentTypeCount)
5187{
5188 const FramebufferAttachment *attachment =
5189 context->getGLState().getDrawFramebuffer()->getDrawBuffer(drawbuffer);
5190 if (attachment)
5191 {
5192 GLenum componentType = attachment->getFormat().info->componentType;
5193 const GLenum *end = validComponentTypes + validComponentTypeCount;
5194 if (std::find(validComponentTypes, end, componentType) == end)
5195 {
5196 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005197 InvalidOperation()
5198 << "No defined conversion between clear value and attachment format.");
Geoff Lang76e65652017-03-27 14:58:02 -04005199 return false;
5200 }
5201 }
5202
5203 return true;
5204}
5205
Jamie Madill5b772312018-03-08 20:28:32 -05005206bool ValidateRobustCompressedTexImageBase(Context *context, GLsizei imageSize, GLsizei dataSize)
Corentin Wallezb2931602017-04-11 15:58:57 -04005207{
5208 if (!ValidateRobustEntryPoint(context, dataSize))
5209 {
5210 return false;
5211 }
5212
Jamie Madill43da7c42018-08-01 11:34:49 -04005213 Buffer *pixelUnpackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack);
Corentin Wallezb2931602017-04-11 15:58:57 -04005214 if (pixelUnpackBuffer == nullptr)
5215 {
5216 if (dataSize < imageSize)
5217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005218 context->handleError(InvalidOperation() << "dataSize must be at least " << imageSize);
Corentin Wallezb2931602017-04-11 15:58:57 -04005219 }
5220 }
5221 return true;
5222}
5223
Jamie Madill5b772312018-03-08 20:28:32 -05005224bool ValidateGetBufferParameterBase(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04005225 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005226 GLenum pname,
5227 bool pointerVersion,
5228 GLsizei *numParams)
5229{
5230 if (numParams)
5231 {
5232 *numParams = 0;
5233 }
5234
Corentin Walleze4477002017-12-01 14:39:58 -05005235 if (!context->isValidBufferBinding(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005236 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005237 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madillbe849e42017-05-02 15:49:00 -04005238 return false;
5239 }
5240
5241 const Buffer *buffer = context->getGLState().getTargetBuffer(target);
5242 if (!buffer)
5243 {
5244 // A null buffer means that "0" is bound to the requested buffer target
Brandon Jones6cad5662017-06-14 13:25:13 -07005245 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005246 return false;
5247 }
5248
5249 const Extensions &extensions = context->getExtensions();
5250
5251 switch (pname)
5252 {
5253 case GL_BUFFER_USAGE:
5254 case GL_BUFFER_SIZE:
5255 break;
5256
5257 case GL_BUFFER_ACCESS_OES:
5258 if (!extensions.mapBuffer)
5259 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005260 context->handleError(InvalidEnum()
5261 << "pname requires OpenGL ES 3.0 or GL_OES_mapbuffer.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005262 return false;
5263 }
5264 break;
5265
5266 case GL_BUFFER_MAPPED:
5267 static_assert(GL_BUFFER_MAPPED == GL_BUFFER_MAPPED_OES, "GL enums should be equal.");
5268 if (context->getClientMajorVersion() < 3 && !extensions.mapBuffer &&
5269 !extensions.mapBufferRange)
5270 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005271 context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0, "
5272 "GL_OES_mapbuffer or "
5273 "GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005274 return false;
5275 }
5276 break;
5277
5278 case GL_BUFFER_MAP_POINTER:
5279 if (!pointerVersion)
5280 {
5281 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005282 InvalidEnum()
5283 << "GL_BUFFER_MAP_POINTER can only be queried with GetBufferPointerv.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005284 return false;
5285 }
5286 break;
5287
5288 case GL_BUFFER_ACCESS_FLAGS:
5289 case GL_BUFFER_MAP_OFFSET:
5290 case GL_BUFFER_MAP_LENGTH:
5291 if (context->getClientMajorVersion() < 3 && !extensions.mapBufferRange)
5292 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005293 context->handleError(InvalidEnum()
5294 << "pname requires OpenGL ES 3.0 or GL_EXT_map_buffer_range.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005295 return false;
5296 }
5297 break;
5298
Geoff Lang79b91402018-10-04 15:11:30 -04005299 case GL_MEMORY_SIZE_ANGLE:
5300 if (!context->getExtensions().memorySize)
5301 {
5302 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5303 return false;
5304 }
5305 break;
5306
Jamie Madillbe849e42017-05-02 15:49:00 -04005307 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005308 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005309 return false;
5310 }
5311
5312 // All buffer parameter queries return one value.
5313 if (numParams)
5314 {
5315 *numParams = 1;
5316 }
5317
5318 return true;
5319}
5320
5321bool ValidateGetRenderbufferParameterivBase(Context *context,
5322 GLenum target,
5323 GLenum pname,
5324 GLsizei *length)
5325{
5326 if (length)
5327 {
5328 *length = 0;
5329 }
5330
5331 if (target != GL_RENDERBUFFER)
5332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005333 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005334 return false;
5335 }
5336
5337 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
5338 if (renderbuffer == nullptr)
5339 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005340 ANGLE_VALIDATION_ERR(context, InvalidOperation(), RenderbufferNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005341 return false;
5342 }
5343
5344 switch (pname)
5345 {
5346 case GL_RENDERBUFFER_WIDTH:
5347 case GL_RENDERBUFFER_HEIGHT:
5348 case GL_RENDERBUFFER_INTERNAL_FORMAT:
5349 case GL_RENDERBUFFER_RED_SIZE:
5350 case GL_RENDERBUFFER_GREEN_SIZE:
5351 case GL_RENDERBUFFER_BLUE_SIZE:
5352 case GL_RENDERBUFFER_ALPHA_SIZE:
5353 case GL_RENDERBUFFER_DEPTH_SIZE:
5354 case GL_RENDERBUFFER_STENCIL_SIZE:
5355 break;
5356
5357 case GL_RENDERBUFFER_SAMPLES_ANGLE:
5358 if (!context->getExtensions().framebufferMultisample)
5359 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005360 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005361 return false;
5362 }
5363 break;
5364
Geoff Lang79b91402018-10-04 15:11:30 -04005365 case GL_MEMORY_SIZE_ANGLE:
5366 if (!context->getExtensions().memorySize)
5367 {
5368 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5369 return false;
5370 }
5371 break;
5372
Jamie Madillbe849e42017-05-02 15:49:00 -04005373 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005374 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005375 return false;
5376 }
5377
5378 if (length)
5379 {
5380 *length = 1;
5381 }
5382 return true;
5383}
5384
5385bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsizei *length)
5386{
5387 if (length)
5388 {
5389 *length = 0;
5390 }
5391
5392 if (GetValidShader(context, shader) == nullptr)
5393 {
5394 return false;
5395 }
5396
5397 switch (pname)
5398 {
5399 case GL_SHADER_TYPE:
5400 case GL_DELETE_STATUS:
5401 case GL_COMPILE_STATUS:
5402 case GL_INFO_LOG_LENGTH:
5403 case GL_SHADER_SOURCE_LENGTH:
5404 break;
5405
5406 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
5407 if (!context->getExtensions().translatedShaderSource)
5408 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005409 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005410 return false;
5411 }
5412 break;
5413
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005414 case GL_COMPLETION_STATUS_KHR:
5415 if (!context->getExtensions().parallelShaderCompile)
5416 {
5417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
5418 return false;
5419 }
5420 break;
5421
Jamie Madillbe849e42017-05-02 15:49:00 -04005422 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005423 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005424 return false;
5425 }
5426
5427 if (length)
5428 {
5429 *length = 1;
5430 }
5431 return true;
5432}
5433
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005434bool ValidateGetTexParameterBase(Context *context,
5435 TextureType target,
5436 GLenum pname,
5437 GLsizei *length)
Jamie Madillbe849e42017-05-02 15:49:00 -04005438{
5439 if (length)
5440 {
5441 *length = 0;
5442 }
5443
5444 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005446 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005447 return false;
5448 }
5449
5450 if (context->getTargetTexture(target) == nullptr)
5451 {
5452 // Should only be possible for external textures
Brandon Jones6cad5662017-06-14 13:25:13 -07005453 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005454 return false;
5455 }
5456
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005457 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5458 {
5459 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5460 return false;
5461 }
5462
Jamie Madillbe849e42017-05-02 15:49:00 -04005463 switch (pname)
5464 {
5465 case GL_TEXTURE_MAG_FILTER:
5466 case GL_TEXTURE_MIN_FILTER:
5467 case GL_TEXTURE_WRAP_S:
5468 case GL_TEXTURE_WRAP_T:
5469 break;
5470
5471 case GL_TEXTURE_USAGE_ANGLE:
5472 if (!context->getExtensions().textureUsage)
5473 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005475 return false;
5476 }
5477 break;
5478
5479 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Luc Ferron1b1a8642018-01-23 15:12:01 -05005480 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
Jamie Madillbe849e42017-05-02 15:49:00 -04005481 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005482 return false;
5483 }
5484 break;
5485
5486 case GL_TEXTURE_IMMUTABLE_FORMAT:
5487 if (context->getClientMajorVersion() < 3 && !context->getExtensions().textureStorage)
5488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005489 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
Jamie Madillbe849e42017-05-02 15:49:00 -04005490 return false;
5491 }
5492 break;
5493
5494 case GL_TEXTURE_WRAP_R:
5495 case GL_TEXTURE_IMMUTABLE_LEVELS:
5496 case GL_TEXTURE_SWIZZLE_R:
5497 case GL_TEXTURE_SWIZZLE_G:
5498 case GL_TEXTURE_SWIZZLE_B:
5499 case GL_TEXTURE_SWIZZLE_A:
5500 case GL_TEXTURE_BASE_LEVEL:
5501 case GL_TEXTURE_MAX_LEVEL:
5502 case GL_TEXTURE_MIN_LOD:
5503 case GL_TEXTURE_MAX_LOD:
5504 case GL_TEXTURE_COMPARE_MODE:
5505 case GL_TEXTURE_COMPARE_FUNC:
5506 if (context->getClientMajorVersion() < 3)
5507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005508 context->handleError(InvalidEnum() << "pname requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005509 return false;
5510 }
5511 break;
5512
5513 case GL_TEXTURE_SRGB_DECODE_EXT:
5514 if (!context->getExtensions().textureSRGBDecode)
5515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005516 context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005517 return false;
5518 }
5519 break;
5520
Yunchao Hebacaa712018-01-30 14:01:39 +08005521 case GL_DEPTH_STENCIL_TEXTURE_MODE:
5522 if (context->getClientVersion() < Version(3, 1))
5523 {
5524 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
5525 return false;
5526 }
5527 break;
5528
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005529 case GL_GENERATE_MIPMAP:
5530 case GL_TEXTURE_CROP_RECT_OES:
5531 // TODO(lfy@google.com): Restrict to GL_OES_draw_texture
5532 // after GL_OES_draw_texture functionality implemented
5533 if (context->getClientMajorVersion() > 1)
5534 {
5535 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
5536 return false;
5537 }
5538 break;
Geoff Lang79b91402018-10-04 15:11:30 -04005539
5540 case GL_MEMORY_SIZE_ANGLE:
5541 if (!context->getExtensions().memorySize)
5542 {
5543 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5544 return false;
5545 }
5546 break;
5547
Till Rathmannb8543632018-10-02 19:46:14 +02005548 case GL_TEXTURE_BORDER_COLOR:
5549 if (!context->getExtensions().textureBorderClamp)
5550 {
5551 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
5552 return false;
5553 }
5554 break;
5555
Jamie Madillbe849e42017-05-02 15:49:00 -04005556 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005557 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005558 return false;
5559 }
5560
5561 if (length)
5562 {
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005563 *length = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005564 }
5565 return true;
5566}
5567
5568bool ValidateGetVertexAttribBase(Context *context,
5569 GLuint index,
5570 GLenum pname,
5571 GLsizei *length,
5572 bool pointer,
5573 bool pureIntegerEntryPoint)
5574{
5575 if (length)
5576 {
5577 *length = 0;
5578 }
5579
5580 if (pureIntegerEntryPoint && context->getClientMajorVersion() < 3)
5581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005582 context->handleError(InvalidOperation() << "Context does not support OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005583 return false;
5584 }
5585
5586 if (index >= context->getCaps().maxVertexAttributes)
5587 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005588 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillbe849e42017-05-02 15:49:00 -04005589 return false;
5590 }
5591
5592 if (pointer)
5593 {
5594 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
5595 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005597 return false;
5598 }
5599 }
5600 else
5601 {
5602 switch (pname)
5603 {
5604 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
5605 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
5606 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
5607 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
5608 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
5609 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
5610 case GL_CURRENT_VERTEX_ATTRIB:
5611 break;
5612
5613 case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
5614 static_assert(
5615 GL_VERTEX_ATTRIB_ARRAY_DIVISOR == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE,
5616 "ANGLE extension enums not equal to GL enums.");
5617 if (context->getClientMajorVersion() < 3 &&
5618 !context->getExtensions().instancedArrays)
5619 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005620 context->handleError(InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR "
5621 "requires OpenGL ES 3.0 or "
5622 "GL_ANGLE_instanced_arrays.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005623 return false;
5624 }
5625 break;
5626
5627 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
5628 if (context->getClientMajorVersion() < 3)
5629 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005630 context->handleError(
5631 InvalidEnum() << "GL_VERTEX_ATTRIB_ARRAY_INTEGER requires OpenGL ES 3.0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005632 return false;
5633 }
5634 break;
5635
5636 case GL_VERTEX_ATTRIB_BINDING:
5637 case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
5638 if (context->getClientVersion() < ES_3_1)
5639 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005640 context->handleError(InvalidEnum()
5641 << "Vertex Attrib Bindings require OpenGL ES 3.1.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005642 return false;
5643 }
5644 break;
5645
5646 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005647 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005648 return false;
5649 }
5650 }
5651
5652 if (length)
5653 {
5654 if (pname == GL_CURRENT_VERTEX_ATTRIB)
5655 {
5656 *length = 4;
5657 }
5658 else
5659 {
5660 *length = 1;
5661 }
5662 }
5663
5664 return true;
5665}
5666
Jamie Madill4928b7c2017-06-20 12:57:39 -04005667bool ValidateReadPixelsBase(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005668 GLint x,
5669 GLint y,
5670 GLsizei width,
5671 GLsizei height,
5672 GLenum format,
5673 GLenum type,
5674 GLsizei bufSize,
5675 GLsizei *length,
5676 GLsizei *columns,
5677 GLsizei *rows,
5678 void *pixels)
5679{
5680 if (length != nullptr)
5681 {
5682 *length = 0;
5683 }
5684 if (rows != nullptr)
5685 {
5686 *rows = 0;
5687 }
5688 if (columns != nullptr)
5689 {
5690 *columns = 0;
5691 }
5692
5693 if (width < 0 || height < 0)
5694 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005695 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005696 return false;
5697 }
5698
Jamie Madillacf2f3a2017-11-21 19:22:44 -05005699 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005700
Jamie Madill427064d2018-04-13 16:20:34 -04005701 if (!ValidateFramebufferComplete(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005702 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005703 return false;
5704 }
5705
Jamie Madille98b1b52018-03-08 09:47:23 -05005706 if (readFramebuffer->id() != 0 && !ValidateFramebufferNotMultisampled(context, readFramebuffer))
Jamie Madillbe849e42017-05-02 15:49:00 -04005707 {
Jamie Madillbe849e42017-05-02 15:49:00 -04005708 return false;
5709 }
5710
Jamie Madill690c8eb2018-03-12 15:20:03 -04005711 Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -04005712 ASSERT(framebuffer);
5713
5714 if (framebuffer->getReadBufferState() == GL_NONE)
5715 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005716 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ReadBufferNone);
Jamie Madillbe849e42017-05-02 15:49:00 -04005717 return false;
5718 }
5719
5720 const FramebufferAttachment *readBuffer = framebuffer->getReadColorbuffer();
5721 // WebGL 1.0 [Section 6.26] Reading From a Missing Attachment
5722 // In OpenGL ES it is undefined what happens when an operation tries to read from a missing
5723 // attachment and WebGL defines it to be an error. We do the check unconditionnaly as the
5724 // situation is an application error that would lead to a crash in ANGLE.
5725 if (readBuffer == nullptr)
5726 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005727 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MissingReadAttachment);
Jamie Madillbe849e42017-05-02 15:49:00 -04005728 return false;
5729 }
5730
Martin Radev28031682017-07-28 14:47:56 +03005731 // ANGLE_multiview, Revision 1:
5732 // ReadPixels generates an INVALID_FRAMEBUFFER_OPERATION error if the multi-view layout of the
Olli Etuaho8acb1b62018-07-30 16:20:54 +03005733 // current read framebuffer is FRAMEBUFFER_MULTIVIEW_SIDE_BY_SIDE_ANGLE or the number of views
5734 // in the current read framebuffer is more than one.
5735 if (framebuffer->readDisallowedByMultiview())
Martin Radev28031682017-07-28 14:47:56 +03005736 {
5737 context->handleError(InvalidFramebufferOperation()
5738 << "Attempting to read from a multi-view framebuffer.");
5739 return false;
5740 }
5741
Geoff Lang280ba992017-04-18 16:30:58 -04005742 if (context->getExtensions().webglCompatibility)
5743 {
5744 // The ES 2.0 spec states that the format must be "among those defined in table 3.4,
5745 // excluding formats LUMINANCE and LUMINANCE_ALPHA.". This requires validating the format
5746 // and type before validating the combination of format and type. However, the
5747 // dEQP-GLES3.functional.negative_api.buffer.read_pixels passes GL_LUMINANCE as a format and
5748 // verifies that GL_INVALID_OPERATION is generated.
5749 // TODO(geofflang): Update this check to be done in all/no cases once this is resolved in
5750 // dEQP/WebGL.
5751 if (!ValidReadPixelsFormatEnum(context, format))
5752 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005753 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFormat);
Geoff Lang280ba992017-04-18 16:30:58 -04005754 return false;
5755 }
5756
5757 if (!ValidReadPixelsTypeEnum(context, type))
5758 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005759 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
Geoff Lang280ba992017-04-18 16:30:58 -04005760 return false;
5761 }
5762 }
5763
Jamie Madill690c8eb2018-03-12 15:20:03 -04005764 GLenum currentFormat = GL_NONE;
5765 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadFormat(context, &currentFormat));
5766
5767 GLenum currentType = GL_NONE;
5768 ANGLE_VALIDATION_TRY(framebuffer->getImplementationColorReadType(context, &currentType));
5769
Jamie Madillbe849e42017-05-02 15:49:00 -04005770 GLenum currentComponentType = readBuffer->getFormat().info->componentType;
5771
5772 bool validFormatTypeCombination =
5773 ValidReadPixelsFormatType(context, currentComponentType, format, type);
5774
5775 if (!(currentFormat == format && currentType == type) && !validFormatTypeCombination)
5776 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005777 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -04005778 return false;
5779 }
5780
5781 // Check for pixel pack buffer related API errors
Jamie Madill43da7c42018-08-01 11:34:49 -04005782 Buffer *pixelPackBuffer = context->getGLState().getTargetBuffer(BufferBinding::PixelPack);
Jamie Madillbe849e42017-05-02 15:49:00 -04005783 if (pixelPackBuffer != nullptr && pixelPackBuffer->isMapped())
5784 {
5785 // ...the buffer object's data store is currently mapped.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005786 context->handleError(InvalidOperation() << "Pixel pack buffer is mapped.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005787 return false;
5788 }
James Darpiniane8a93c62018-01-04 18:02:24 -08005789 if (context->getExtensions().webglCompatibility && pixelPackBuffer != nullptr &&
5790 pixelPackBuffer->isBoundForTransformFeedbackAndOtherUse())
5791 {
5792 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelPackBufferBoundForTransformFeedback);
5793 return false;
5794 }
Jamie Madillbe849e42017-05-02 15:49:00 -04005795
5796 // .. the data would be packed to the buffer object such that the memory writes required
5797 // would exceed the data store size.
5798 const InternalFormat &formatInfo = GetInternalFormatInfo(format, type);
Jamie Madill43da7c42018-08-01 11:34:49 -04005799 const Extents size(width, height, 1);
Jamie Madillbe849e42017-05-02 15:49:00 -04005800 const auto &pack = context->getGLState().getPackState();
5801
Jamie Madillca2ff382018-07-11 09:01:17 -04005802 GLuint endByte = 0;
5803 if (!formatInfo.computePackUnpackEndByte(type, size, pack, false, &endByte))
Jamie Madillbe849e42017-05-02 15:49:00 -04005804 {
Jamie Madillca2ff382018-07-11 09:01:17 -04005805 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005806 return false;
5807 }
5808
Jamie Madillbe849e42017-05-02 15:49:00 -04005809 if (bufSize >= 0)
5810 {
5811 if (pixelPackBuffer == nullptr && static_cast<size_t>(bufSize) < endByte)
5812 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005813 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005814 return false;
5815 }
5816 }
5817
5818 if (pixelPackBuffer != nullptr)
5819 {
5820 CheckedNumeric<size_t> checkedEndByte(endByte);
5821 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(pixels));
5822 checkedEndByte += checkedOffset;
5823
5824 if (checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelPackBuffer->getSize()))
5825 {
5826 // Overflow past the end of the buffer
Brandon Jones6cad5662017-06-14 13:25:13 -07005827 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ParamOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005828 return false;
5829 }
5830 }
5831
5832 if (pixelPackBuffer == nullptr && length != nullptr)
5833 {
5834 if (endByte > static_cast<size_t>(std::numeric_limits<GLsizei>::max()))
5835 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005836 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madillbe849e42017-05-02 15:49:00 -04005837 return false;
5838 }
5839
5840 *length = static_cast<GLsizei>(endByte);
5841 }
5842
Geoff Langa953b522018-02-21 16:56:23 -05005843 auto getClippedExtent = [](GLint start, GLsizei length, int bufferSize, GLsizei *outExtent) {
Jamie Madillbe849e42017-05-02 15:49:00 -04005844 angle::CheckedNumeric<int> clippedExtent(length);
5845 if (start < 0)
5846 {
5847 // "subtract" the area that is less than 0
5848 clippedExtent += start;
5849 }
5850
Geoff Langa953b522018-02-21 16:56:23 -05005851 angle::CheckedNumeric<int> readExtent = start;
5852 readExtent += length;
5853 if (!readExtent.IsValid())
5854 {
5855 return false;
5856 }
5857
5858 if (readExtent.ValueOrDie() > bufferSize)
Jamie Madillbe849e42017-05-02 15:49:00 -04005859 {
5860 // Subtract the region to the right of the read buffer
5861 clippedExtent -= (readExtent - bufferSize);
5862 }
5863
5864 if (!clippedExtent.IsValid())
5865 {
Geoff Langa953b522018-02-21 16:56:23 -05005866 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04005867 }
5868
Geoff Langa953b522018-02-21 16:56:23 -05005869 *outExtent = std::max(clippedExtent.ValueOrDie(), 0);
5870 return true;
Jamie Madillbe849e42017-05-02 15:49:00 -04005871 };
5872
Geoff Langa953b522018-02-21 16:56:23 -05005873 GLsizei writtenColumns = 0;
5874 if (!getClippedExtent(x, width, readBuffer->getSize().width, &writtenColumns))
5875 {
5876 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
5877 return false;
5878 }
5879
5880 GLsizei writtenRows = 0;
5881 if (!getClippedExtent(y, height, readBuffer->getSize().height, &writtenRows))
5882 {
5883 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
5884 return false;
5885 }
5886
Jamie Madillbe849e42017-05-02 15:49:00 -04005887 if (columns != nullptr)
5888 {
Geoff Langa953b522018-02-21 16:56:23 -05005889 *columns = writtenColumns;
Jamie Madillbe849e42017-05-02 15:49:00 -04005890 }
5891
5892 if (rows != nullptr)
5893 {
Geoff Langa953b522018-02-21 16:56:23 -05005894 *rows = writtenRows;
Jamie Madillbe849e42017-05-02 15:49:00 -04005895 }
5896
5897 return true;
5898}
5899
5900template <typename ParamType>
5901bool ValidateTexParameterBase(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005902 TextureType target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005903 GLenum pname,
5904 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02005905 bool vectorParams,
Jamie Madillbe849e42017-05-02 15:49:00 -04005906 const ParamType *params)
5907{
5908 if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
5909 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005910 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005911 return false;
5912 }
5913
5914 if (context->getTargetTexture(target) == nullptr)
5915 {
5916 // Should only be possible for external textures
Brandon Jones6cad5662017-06-14 13:25:13 -07005917 ANGLE_VALIDATION_ERR(context, InvalidEnum(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04005918 return false;
5919 }
5920
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005921 const GLsizei minBufSize = GetTexParameterCount(pname);
Jamie Madillbe849e42017-05-02 15:49:00 -04005922 if (bufSize >= 0 && bufSize < minBufSize)
5923 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005924 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
Jamie Madillbe849e42017-05-02 15:49:00 -04005925 return false;
5926 }
5927
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005928 if (context->getClientMajorVersion() == 1 && !IsValidGLES1TextureParameter(pname))
5929 {
5930 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5931 return false;
5932 }
5933
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 switch (pname)
5935 {
5936 case GL_TEXTURE_WRAP_R:
5937 case GL_TEXTURE_SWIZZLE_R:
5938 case GL_TEXTURE_SWIZZLE_G:
5939 case GL_TEXTURE_SWIZZLE_B:
5940 case GL_TEXTURE_SWIZZLE_A:
5941 case GL_TEXTURE_BASE_LEVEL:
5942 case GL_TEXTURE_MAX_LEVEL:
5943 case GL_TEXTURE_COMPARE_MODE:
5944 case GL_TEXTURE_COMPARE_FUNC:
5945 case GL_TEXTURE_MIN_LOD:
5946 case GL_TEXTURE_MAX_LOD:
5947 if (context->getClientMajorVersion() < 3)
5948 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005949 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005950 return false;
5951 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005952 if (target == TextureType::External && !context->getExtensions().eglImageExternalEssl3)
Jamie Madillbe849e42017-05-02 15:49:00 -04005953 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005954 context->handleError(InvalidEnum() << "ES3 texture parameters are not "
5955 "available without "
5956 "GL_OES_EGL_image_external_essl3.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005957 return false;
5958 }
5959 break;
5960
Lingfeng Yangf97641c2018-06-21 19:22:45 -07005961 case GL_GENERATE_MIPMAP:
5962 case GL_TEXTURE_CROP_RECT_OES:
5963 if (context->getClientMajorVersion() > 1)
5964 {
5965 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
5966 return false;
5967 }
5968 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04005969 default:
5970 break;
5971 }
5972
Olli Etuahod310a432018-08-24 15:40:23 +03005973 if (target == TextureType::_2DMultisample || target == TextureType::_2DMultisampleArray)
JiangYizhou4cff8d62017-07-06 14:54:09 +08005974 {
5975 switch (pname)
5976 {
5977 case GL_TEXTURE_MIN_FILTER:
5978 case GL_TEXTURE_MAG_FILTER:
5979 case GL_TEXTURE_WRAP_S:
5980 case GL_TEXTURE_WRAP_T:
5981 case GL_TEXTURE_WRAP_R:
5982 case GL_TEXTURE_MIN_LOD:
5983 case GL_TEXTURE_MAX_LOD:
5984 case GL_TEXTURE_COMPARE_MODE:
5985 case GL_TEXTURE_COMPARE_FUNC:
Till Rathmannb8543632018-10-02 19:46:14 +02005986 case GL_TEXTURE_BORDER_COLOR:
JiangYizhou4cff8d62017-07-06 14:54:09 +08005987 context->handleError(InvalidEnum()
5988 << "Invalid parameter for 2D multisampled textures.");
5989 return false;
5990 }
5991 }
5992
Jamie Madillbe849e42017-05-02 15:49:00 -04005993 switch (pname)
5994 {
5995 case GL_TEXTURE_WRAP_S:
5996 case GL_TEXTURE_WRAP_T:
5997 case GL_TEXTURE_WRAP_R:
Lingfeng Yang038dd532018-03-29 17:31:52 -07005998 {
5999 bool restrictedWrapModes =
6000 target == TextureType::External || target == TextureType::Rectangle;
6001 if (!ValidateTextureWrapModeValue(context, params, restrictedWrapModes))
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006003 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006004 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006005 }
6006 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006007
6008 case GL_TEXTURE_MIN_FILTER:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006009 {
6010 bool restrictedMinFilter =
6011 target == TextureType::External || target == TextureType::Rectangle;
6012 if (!ValidateTextureMinFilterValue(context, params, restrictedMinFilter))
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006014 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006015 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006016 }
6017 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006018
6019 case GL_TEXTURE_MAG_FILTER:
6020 if (!ValidateTextureMagFilterValue(context, params))
6021 {
6022 return false;
6023 }
6024 break;
6025
6026 case GL_TEXTURE_USAGE_ANGLE:
Geoff Lang91ab54b2017-10-30 15:12:42 -04006027 if (!context->getExtensions().textureUsage)
6028 {
6029 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6030 return false;
6031 }
6032
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 switch (ConvertToGLenum(params[0]))
6034 {
6035 case GL_NONE:
6036 case GL_FRAMEBUFFER_ATTACHMENT_ANGLE:
6037 break;
6038
6039 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 return false;
6042 }
6043 break;
6044
6045 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
Lingfeng Yang038dd532018-03-29 17:31:52 -07006046 {
6047 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6048 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 {
Lingfeng Yang038dd532018-03-29 17:31:52 -07006050 return false;
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 }
Lingfeng Yang038dd532018-03-29 17:31:52 -07006052 ASSERT(static_cast<ParamType>(paramValue) == params[0]);
6053 }
6054 break;
Jamie Madillbe849e42017-05-02 15:49:00 -04006055
6056 case GL_TEXTURE_MIN_LOD:
6057 case GL_TEXTURE_MAX_LOD:
6058 // any value is permissible
6059 break;
6060
6061 case GL_TEXTURE_COMPARE_MODE:
6062 if (!ValidateTextureCompareModeValue(context, params))
6063 {
6064 return false;
6065 }
6066 break;
6067
6068 case GL_TEXTURE_COMPARE_FUNC:
6069 if (!ValidateTextureCompareFuncValue(context, params))
6070 {
6071 return false;
6072 }
6073 break;
6074
6075 case GL_TEXTURE_SWIZZLE_R:
6076 case GL_TEXTURE_SWIZZLE_G:
6077 case GL_TEXTURE_SWIZZLE_B:
6078 case GL_TEXTURE_SWIZZLE_A:
6079 switch (ConvertToGLenum(params[0]))
6080 {
6081 case GL_RED:
6082 case GL_GREEN:
6083 case GL_BLUE:
6084 case GL_ALPHA:
6085 case GL_ZERO:
6086 case GL_ONE:
6087 break;
6088
6089 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006090 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006091 return false;
6092 }
6093 break;
6094
6095 case GL_TEXTURE_BASE_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006096 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006098 context->handleError(InvalidValue() << "Base level must be at least 0.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006101 if (target == TextureType::External && static_cast<GLuint>(params[0]) != 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006103 context->handleError(InvalidOperation()
6104 << "Base level must be 0 for external textures.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006105 return false;
6106 }
Olli Etuahod310a432018-08-24 15:40:23 +03006107 if ((target == TextureType::_2DMultisample ||
6108 target == TextureType::_2DMultisampleArray) &&
6109 static_cast<GLuint>(params[0]) != 0)
JiangYizhou4cff8d62017-07-06 14:54:09 +08006110 {
6111 context->handleError(InvalidOperation()
6112 << "Base level must be 0 for multisampled textures.");
6113 return false;
6114 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006115 if (target == TextureType::Rectangle && static_cast<GLuint>(params[0]) != 0)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006116 {
6117 context->handleError(InvalidOperation()
6118 << "Base level must be 0 for rectangle textures.");
6119 return false;
6120 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006121 break;
6122
6123 case GL_TEXTURE_MAX_LEVEL:
Geoff Langfb7685f2017-11-13 11:44:11 -05006124 if (ConvertToGLint(params[0]) < 0)
Jamie Madillbe849e42017-05-02 15:49:00 -04006125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006126 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
6129 break;
6130
6131 case GL_DEPTH_STENCIL_TEXTURE_MODE:
6132 if (context->getClientVersion() < Version(3, 1))
6133 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006134 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumRequiresGLES31);
Jamie Madillbe849e42017-05-02 15:49:00 -04006135 return false;
6136 }
6137 switch (ConvertToGLenum(params[0]))
6138 {
6139 case GL_DEPTH_COMPONENT:
6140 case GL_STENCIL_INDEX:
6141 break;
6142
6143 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 return false;
6146 }
6147 break;
6148
6149 case GL_TEXTURE_SRGB_DECODE_EXT:
6150 if (!ValidateTextureSRGBDecodeValue(context, params))
6151 {
6152 return false;
6153 }
6154 break;
6155
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006156 case GL_GENERATE_MIPMAP:
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006157 if (context->getClientMajorVersion() > 1)
6158 {
6159 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
6160 return false;
6161 }
6162 break;
Till Rathmannb8543632018-10-02 19:46:14 +02006163
6164 case GL_TEXTURE_CROP_RECT_OES:
6165 if (context->getClientMajorVersion() > 1)
6166 {
6167 ANGLE_VALIDATION_ERR(context, InvalidEnum(), GLES1Only);
6168 return false;
6169 }
6170 if (!vectorParams)
6171 {
6172 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
6173 return false;
6174 }
6175 break;
6176
6177 case GL_TEXTURE_BORDER_COLOR:
6178 if (!context->getExtensions().textureBorderClamp)
6179 {
6180 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
6181 return false;
6182 }
6183 if (!vectorParams)
6184 {
6185 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InsufficientBufferSize);
6186 return false;
6187 }
6188 break;
6189
Jamie Madillbe849e42017-05-02 15:49:00 -04006190 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006191 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006192 return false;
6193 }
6194
6195 return true;
6196}
6197
Till Rathmannb8543632018-10-02 19:46:14 +02006198template bool ValidateTexParameterBase(Context *,
6199 TextureType,
6200 GLenum,
6201 GLsizei,
6202 bool,
6203 const GLfloat *);
6204template bool ValidateTexParameterBase(Context *,
6205 TextureType,
6206 GLenum,
6207 GLsizei,
6208 bool,
6209 const GLint *);
6210template bool ValidateTexParameterBase(Context *,
6211 TextureType,
6212 GLenum,
6213 GLsizei,
6214 bool,
6215 const GLuint *);
Jamie Madillbe849e42017-05-02 15:49:00 -04006216
Jamie Madill5b772312018-03-08 20:28:32 -05006217bool ValidateVertexAttribIndex(Context *context, GLuint index)
Jamie Madill12e957f2017-08-26 21:42:26 -04006218{
6219 if (index >= MAX_VERTEX_ATTRIBS)
6220 {
6221 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
6222 return false;
6223 }
6224
6225 return true;
6226}
6227
6228bool ValidateGetActiveUniformBlockivBase(Context *context,
6229 GLuint program,
6230 GLuint uniformBlockIndex,
6231 GLenum pname,
6232 GLsizei *length)
6233{
6234 if (length)
6235 {
6236 *length = 0;
6237 }
6238
6239 if (context->getClientMajorVersion() < 3)
6240 {
6241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6242 return false;
6243 }
6244
6245 Program *programObject = GetValidProgram(context, program);
6246 if (!programObject)
6247 {
6248 return false;
6249 }
6250
6251 if (uniformBlockIndex >= programObject->getActiveUniformBlockCount())
6252 {
6253 context->handleError(InvalidValue()
6254 << "uniformBlockIndex exceeds active uniform block count.");
6255 return false;
6256 }
6257
6258 switch (pname)
6259 {
6260 case GL_UNIFORM_BLOCK_BINDING:
6261 case GL_UNIFORM_BLOCK_DATA_SIZE:
6262 case GL_UNIFORM_BLOCK_NAME_LENGTH:
6263 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
6264 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
6265 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
6266 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
6267 break;
6268
6269 default:
6270 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6271 return false;
6272 }
6273
6274 if (length)
6275 {
6276 if (pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES)
6277 {
Jiajia Qin729b2c62017-08-14 09:36:11 +08006278 const InterfaceBlock &uniformBlock =
Jamie Madill12e957f2017-08-26 21:42:26 -04006279 programObject->getUniformBlockByIndex(uniformBlockIndex);
6280 *length = static_cast<GLsizei>(uniformBlock.memberIndexes.size());
6281 }
6282 else
6283 {
6284 *length = 1;
6285 }
6286 }
6287
6288 return true;
6289}
6290
Jamie Madill9696d072017-08-26 23:19:57 -04006291template <typename ParamType>
6292bool ValidateSamplerParameterBase(Context *context,
6293 GLuint sampler,
6294 GLenum pname,
6295 GLsizei bufSize,
Till Rathmannb8543632018-10-02 19:46:14 +02006296 bool vectorParams,
Jamie Madill9696d072017-08-26 23:19:57 -04006297 ParamType *params)
6298{
6299 if (context->getClientMajorVersion() < 3)
6300 {
6301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6302 return false;
6303 }
6304
6305 if (!context->isSampler(sampler))
6306 {
6307 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler);
6308 return false;
6309 }
6310
Till Rathmannb8543632018-10-02 19:46:14 +02006311 const GLsizei minBufSize = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006312 if (bufSize >= 0 && bufSize < minBufSize)
6313 {
6314 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
6315 return false;
6316 }
6317
6318 switch (pname)
6319 {
6320 case GL_TEXTURE_WRAP_S:
6321 case GL_TEXTURE_WRAP_T:
6322 case GL_TEXTURE_WRAP_R:
6323 if (!ValidateTextureWrapModeValue(context, params, false))
6324 {
6325 return false;
6326 }
6327 break;
6328
6329 case GL_TEXTURE_MIN_FILTER:
6330 if (!ValidateTextureMinFilterValue(context, params, false))
6331 {
6332 return false;
6333 }
6334 break;
6335
6336 case GL_TEXTURE_MAG_FILTER:
6337 if (!ValidateTextureMagFilterValue(context, params))
6338 {
6339 return false;
6340 }
6341 break;
6342
6343 case GL_TEXTURE_MIN_LOD:
6344 case GL_TEXTURE_MAX_LOD:
6345 // any value is permissible
6346 break;
6347
6348 case GL_TEXTURE_COMPARE_MODE:
6349 if (!ValidateTextureCompareModeValue(context, params))
6350 {
6351 return false;
6352 }
6353 break;
6354
6355 case GL_TEXTURE_COMPARE_FUNC:
6356 if (!ValidateTextureCompareFuncValue(context, params))
6357 {
6358 return false;
6359 }
6360 break;
6361
6362 case GL_TEXTURE_SRGB_DECODE_EXT:
6363 if (!ValidateTextureSRGBDecodeValue(context, params))
6364 {
6365 return false;
6366 }
6367 break;
6368
Luc Ferron1b1a8642018-01-23 15:12:01 -05006369 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6370 {
6371 GLfloat paramValue = static_cast<GLfloat>(params[0]);
6372 if (!ValidateTextureMaxAnisotropyValue(context, paramValue))
6373 {
6374 return false;
6375 }
6376 }
6377 break;
6378
Till Rathmannb8543632018-10-02 19:46:14 +02006379 case GL_TEXTURE_BORDER_COLOR:
6380 if (!context->getExtensions().textureBorderClamp)
6381 {
6382 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
6383 return false;
6384 }
6385 if (!vectorParams)
6386 {
6387 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InsufficientBufferSize);
6388 return false;
6389 }
6390 break;
6391
Jamie Madill9696d072017-08-26 23:19:57 -04006392 default:
6393 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6394 return false;
6395 }
6396
6397 return true;
6398}
6399
Till Rathmannb8543632018-10-02 19:46:14 +02006400template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLfloat *);
6401template bool ValidateSamplerParameterBase(Context *, GLuint, GLenum, GLsizei, bool, GLint *);
6402template bool ValidateSamplerParameterBase(Context *,
6403 GLuint,
6404 GLenum,
6405 GLsizei,
6406 bool,
6407 const GLuint *);
Jamie Madill9696d072017-08-26 23:19:57 -04006408
6409bool ValidateGetSamplerParameterBase(Context *context,
6410 GLuint sampler,
6411 GLenum pname,
6412 GLsizei *length)
6413{
6414 if (length)
6415 {
6416 *length = 0;
6417 }
6418
6419 if (context->getClientMajorVersion() < 3)
6420 {
6421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
6422 return false;
6423 }
6424
6425 if (!context->isSampler(sampler))
6426 {
6427 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidSampler);
6428 return false;
6429 }
6430
6431 switch (pname)
6432 {
6433 case GL_TEXTURE_WRAP_S:
6434 case GL_TEXTURE_WRAP_T:
6435 case GL_TEXTURE_WRAP_R:
6436 case GL_TEXTURE_MIN_FILTER:
6437 case GL_TEXTURE_MAG_FILTER:
6438 case GL_TEXTURE_MIN_LOD:
6439 case GL_TEXTURE_MAX_LOD:
6440 case GL_TEXTURE_COMPARE_MODE:
6441 case GL_TEXTURE_COMPARE_FUNC:
6442 break;
6443
Luc Ferron1b1a8642018-01-23 15:12:01 -05006444 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
6445 if (!ValidateTextureMaxAnisotropyExtensionEnabled(context))
6446 {
6447 return false;
6448 }
6449 break;
6450
Jamie Madill9696d072017-08-26 23:19:57 -04006451 case GL_TEXTURE_SRGB_DECODE_EXT:
6452 if (!context->getExtensions().textureSRGBDecode)
6453 {
6454 context->handleError(InvalidEnum() << "GL_EXT_texture_sRGB_decode is not enabled.");
6455 return false;
6456 }
6457 break;
6458
Till Rathmannb8543632018-10-02 19:46:14 +02006459 case GL_TEXTURE_BORDER_COLOR:
6460 if (!context->getExtensions().textureBorderClamp)
6461 {
6462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ExtensionNotEnabled);
6463 return false;
6464 }
6465 break;
6466
Jamie Madill9696d072017-08-26 23:19:57 -04006467 default:
6468 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6469 return false;
6470 }
6471
6472 if (length)
6473 {
Till Rathmannb8543632018-10-02 19:46:14 +02006474 *length = GetSamplerParameterCount(pname);
Jamie Madill9696d072017-08-26 23:19:57 -04006475 }
6476 return true;
6477}
6478
6479bool ValidateGetInternalFormativBase(Context *context,
6480 GLenum target,
6481 GLenum internalformat,
6482 GLenum pname,
6483 GLsizei bufSize,
6484 GLsizei *numParams)
6485{
6486 if (numParams)
6487 {
6488 *numParams = 0;
6489 }
6490
6491 if (context->getClientMajorVersion() < 3)
6492 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08006493 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES3Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006494 return false;
6495 }
6496
6497 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
Yuly Novikovf15f8862018-06-04 18:59:41 -04006498 if (!formatCaps.renderbuffer)
Jamie Madill9696d072017-08-26 23:19:57 -04006499 {
6500 context->handleError(InvalidEnum() << "Internal format is not renderable.");
6501 return false;
6502 }
6503
6504 switch (target)
6505 {
6506 case GL_RENDERBUFFER:
6507 break;
6508
6509 case GL_TEXTURE_2D_MULTISAMPLE:
Yizhou Jiang7818a852018-09-06 15:02:04 +08006510 if (context->getClientVersion() < ES_3_1 &&
6511 !context->getExtensions().textureMultisample)
Jamie Madill9696d072017-08-26 23:19:57 -04006512 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006513 ANGLE_VALIDATION_ERR(context, InvalidEnum(),
6514 MultisampleTextureExtensionOrES31Required);
Jamie Madill9696d072017-08-26 23:19:57 -04006515 return false;
6516 }
6517 break;
Olli Etuaho064458a2018-08-30 14:02:02 +03006518 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES:
6519 if (!context->getExtensions().textureStorageMultisample2DArray)
Olli Etuahod310a432018-08-24 15:40:23 +03006520 {
6521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
6522 return false;
6523 }
6524 break;
Jamie Madill9696d072017-08-26 23:19:57 -04006525 default:
6526 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTarget);
6527 return false;
6528 }
6529
6530 if (bufSize < 0)
6531 {
6532 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
6533 return false;
6534 }
6535
6536 GLsizei maxWriteParams = 0;
6537 switch (pname)
6538 {
6539 case GL_NUM_SAMPLE_COUNTS:
6540 maxWriteParams = 1;
6541 break;
6542
6543 case GL_SAMPLES:
6544 maxWriteParams = static_cast<GLsizei>(formatCaps.sampleCounts.size());
6545 break;
6546
6547 default:
6548 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
6549 return false;
6550 }
6551
6552 if (numParams)
6553 {
6554 // glGetInternalFormativ will not overflow bufSize
6555 *numParams = std::min(bufSize, maxWriteParams);
6556 }
6557
6558 return true;
6559}
6560
Jamie Madille98b1b52018-03-08 09:47:23 -05006561bool ValidateFramebufferNotMultisampled(Context *context, Framebuffer *framebuffer)
6562{
Jamie Madill427064d2018-04-13 16:20:34 -04006563 if (framebuffer->getSamples(context) != 0)
Jamie Madille98b1b52018-03-08 09:47:23 -05006564 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03006565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidMultisampledFramebufferOperation);
Jamie Madille98b1b52018-03-08 09:47:23 -05006566 return false;
6567 }
6568 return true;
6569}
6570
Lingfeng Yang038dd532018-03-29 17:31:52 -07006571bool ValidateMultitextureUnit(Context *context, GLenum texture)
6572{
6573 if (texture < GL_TEXTURE0 || texture >= GL_TEXTURE0 + context->getCaps().maxMultitextureUnits)
6574 {
6575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMultitextureUnit);
6576 return false;
6577 }
6578 return true;
6579}
6580
Olli Etuahod310a432018-08-24 15:40:23 +03006581bool ValidateTexStorageMultisample(Context *context,
6582 TextureType target,
6583 GLsizei samples,
6584 GLint internalFormat,
6585 GLsizei width,
6586 GLsizei height)
6587{
6588 const Caps &caps = context->getCaps();
6589 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
6590 static_cast<GLuint>(height) > caps.max2DTextureSize)
6591 {
6592 ANGLE_VALIDATION_ERR(context, InvalidValue(), TextureWidthOrHeightOutOfRange);
6593 return false;
6594 }
6595
6596 if (samples == 0)
6597 {
6598 ANGLE_VALIDATION_ERR(context, InvalidValue(), SamplesZero);
6599 return false;
6600 }
6601
6602 const TextureCaps &formatCaps = context->getTextureCaps().get(internalFormat);
6603 if (!formatCaps.textureAttachment)
6604 {
6605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), RenderableInternalFormat);
6606 return false;
6607 }
6608
6609 // The ES3.1 spec(section 8.8) states that an INVALID_ENUM error is generated if internalformat
6610 // is one of the unsized base internalformats listed in table 8.11.
6611 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalFormat);
6612 if (formatInfo.internalFormat == GL_NONE)
6613 {
6614 ANGLE_VALIDATION_ERR(context, InvalidEnum(), UnsizedInternalFormatUnsupported);
6615 return false;
6616 }
6617
6618 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6619 {
6620 ANGLE_VALIDATION_ERR(context, InvalidOperation(), SamplesOutOfRange);
6621 return false;
6622 }
6623
6624 Texture *texture = context->getTargetTexture(target);
6625 if (!texture || texture->id() == 0)
6626 {
6627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ZeroBoundToTarget);
6628 return false;
6629 }
6630
6631 if (texture->getImmutableFormat())
6632 {
6633 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ImmutableTextureBound);
6634 return false;
6635 }
6636 return true;
6637}
6638
Yizhou Jiang7818a852018-09-06 15:02:04 +08006639bool ValidateTexStorage2DMultisampleBase(Context *context,
6640 TextureType target,
6641 GLsizei samples,
6642 GLint internalFormat,
6643 GLsizei width,
6644 GLsizei height)
6645{
6646 if (target != TextureType::_2DMultisample)
6647 {
6648 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTarget);
6649 return false;
6650 }
6651
6652 if (width < 1 || height < 1)
6653 {
6654 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
6655 return false;
6656 }
6657
6658 return ValidateTexStorageMultisample(context, target, samples, internalFormat, width, height);
6659}
Jamie Madillc29968b2016-01-20 11:17:23 -05006660} // namespace gl