blob: d8215671f1489b66a9221cd1c815e6fb145b94c8 [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// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Geoff Lang63458a32017-10-30 15:16:53 -0400310bool IsValidCopyTextureDestinationTargetEnum(Context *context, GLenum target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
314 case GL_TEXTURE_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400315 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
316 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
317 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
318 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
319 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
320 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400323 case GL_TEXTURE_RECTANGLE_ANGLE:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Geoff Lang63458a32017-10-30 15:16:53 -0400331bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
332{
333 if (IsCubeMapTextureTarget(target))
334 {
335 return textureType == GL_TEXTURE_CUBE_MAP;
336 }
337 else
338 {
339 return textureType == target;
340 }
341}
342
Geoff Lang97073d12016-04-20 10:42:34 -0700343bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
344{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400345 switch (target)
Geoff Lang97073d12016-04-20 10:42:34 -0700346 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400347 case GL_TEXTURE_2D:
348 return true;
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400349 case GL_TEXTURE_RECTANGLE_ANGLE:
350 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400351
352 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
353 // supported
354
355 default:
356 return false;
357 }
358}
359
360bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level)
361{
Geoff Lang3847f942017-07-12 11:17:28 -0400362 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 {
364 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700365 }
366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 if (level > 0 && context->getClientVersion() < ES_3_0)
368 {
369 return false;
370 }
Geoff Lang97073d12016-04-20 10:42:34 -0700371
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 return true;
373}
374
375bool IsValidCopyTextureDestinationLevel(Context *context,
376 GLenum target,
377 GLint level,
378 GLsizei width,
379 GLsizei height)
380{
Geoff Lang3847f942017-07-12 11:17:28 -0400381 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400382 {
383 return false;
384 }
385
Geoff Lang4f0e0032017-05-01 16:04:35 -0400386 const Caps &caps = context->getCaps();
387 if (target == GL_TEXTURE_2D)
388 {
389 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
390 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
391 {
392 return false;
393 }
394 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400395 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
396 {
397 ASSERT(level == 0);
398 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
399 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
400 {
401 return false;
402 }
403 }
Geoff Lang4f0e0032017-05-01 16:04:35 -0400404 else if (IsCubeMapTextureTarget(target))
405 {
406 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
407 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
408 {
409 return false;
410 }
411 }
412
413 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700414}
415
Jamie Madillc1d770e2017-04-13 17:31:24 -0400416bool IsValidStencilFunc(GLenum func)
417{
418 switch (func)
419 {
420 case GL_NEVER:
421 case GL_ALWAYS:
422 case GL_LESS:
423 case GL_LEQUAL:
424 case GL_EQUAL:
425 case GL_GEQUAL:
426 case GL_GREATER:
427 case GL_NOTEQUAL:
428 return true;
429
430 default:
431 return false;
432 }
433}
434
435bool IsValidStencilFace(GLenum face)
436{
437 switch (face)
438 {
439 case GL_FRONT:
440 case GL_BACK:
441 case GL_FRONT_AND_BACK:
442 return true;
443
444 default:
445 return false;
446 }
447}
448
449bool IsValidStencilOp(GLenum op)
450{
451 switch (op)
452 {
453 case GL_ZERO:
454 case GL_KEEP:
455 case GL_REPLACE:
456 case GL_INCR:
457 case GL_DECR:
458 case GL_INVERT:
459 case GL_INCR_WRAP:
460 case GL_DECR_WRAP:
461 return true;
462
463 default:
464 return false;
465 }
466}
467
Jamie Madillbe849e42017-05-02 15:49:00 -0400468bool ValidateES2CopyTexImageParameters(ValidationContext *context,
469 GLenum target,
470 GLint level,
471 GLenum internalformat,
472 bool isSubImage,
473 GLint xoffset,
474 GLint yoffset,
475 GLint x,
476 GLint y,
477 GLsizei width,
478 GLsizei height,
479 GLint border)
480{
481 if (!ValidTexture2DDestinationTarget(context, target))
482 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700483 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400484 return false;
485 }
486
487 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
488 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500489 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400490 return false;
491 }
492
493 Format textureFormat = Format::Invalid();
494 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
495 xoffset, yoffset, 0, x, y, width, height, border,
496 &textureFormat))
497 {
498 return false;
499 }
500
501 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
502 GLenum colorbufferFormat =
503 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
504 const auto &formatInfo = *textureFormat.info;
505
506 // [OpenGL ES 2.0.24] table 3.9
507 if (isSubImage)
508 {
509 switch (formatInfo.format)
510 {
511 case GL_ALPHA:
512 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400513 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
514 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400515 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400517 return false;
518 }
519 break;
520 case GL_LUMINANCE:
521 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
522 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
523 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400524 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
525 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400526 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700527 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400528 return false;
529 }
530 break;
531 case GL_RED_EXT:
532 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
533 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
534 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
535 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
536 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400537 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
538 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400539 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400541 return false;
542 }
543 break;
544 case GL_RG_EXT:
545 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
546 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
547 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
548 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400549 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
550 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400551 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400553 return false;
554 }
555 break;
556 case GL_RGB:
557 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
558 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
559 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400560 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
561 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400562 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 return false;
565 }
566 break;
567 case GL_LUMINANCE_ALPHA:
568 case GL_RGBA:
569 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400570 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
571 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400572 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700573 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400574 return false;
575 }
576 break;
577 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
578 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
579 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
580 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
581 case GL_ETC1_RGB8_OES:
582 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
583 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
584 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
585 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
586 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700587 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 case GL_DEPTH_COMPONENT:
590 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700591 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400592 return false;
593 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700594 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400595 return false;
596 }
597
598 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
599 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700600 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400601 return false;
602 }
603 }
604 else
605 {
606 switch (internalformat)
607 {
608 case GL_ALPHA:
609 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
610 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
611 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
612 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700613 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400614 return false;
615 }
616 break;
617 case GL_LUMINANCE:
618 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
619 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
620 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
621 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
622 colorbufferFormat != GL_BGR5_A1_ANGLEX)
623 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700624 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400625 return false;
626 }
627 break;
628 case GL_RED_EXT:
629 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
630 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
631 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
632 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
633 colorbufferFormat != GL_BGR5_A1_ANGLEX)
634 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700635 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400636 return false;
637 }
638 break;
639 case GL_RG_EXT:
640 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
641 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
642 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
643 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
644 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700645 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400646 return false;
647 }
648 break;
649 case GL_RGB:
650 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
651 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
652 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
653 colorbufferFormat != GL_BGR5_A1_ANGLEX)
654 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700655 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400656 return false;
657 }
658 break;
659 case GL_LUMINANCE_ALPHA:
660 case GL_RGBA:
661 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
662 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
663 colorbufferFormat != GL_BGR5_A1_ANGLEX)
664 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400666 return false;
667 }
668 break;
669 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
670 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
671 if (context->getExtensions().textureCompressionDXT1)
672 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700673 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400674 return false;
675 }
676 else
677 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700678 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400679 return false;
680 }
681 break;
682 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
683 if (context->getExtensions().textureCompressionDXT3)
684 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700685 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400686 return false;
687 }
688 else
689 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700690 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400691 return false;
692 }
693 break;
694 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
695 if (context->getExtensions().textureCompressionDXT5)
696 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700697 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400698 return false;
699 }
700 else
701 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700702 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400703 return false;
704 }
705 break;
706 case GL_ETC1_RGB8_OES:
707 if (context->getExtensions().compressedETC1RGB8Texture)
708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500709 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400710 return false;
711 }
712 else
713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500714 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400715 return false;
716 }
717 break;
718 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
719 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
720 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
721 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
722 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
723 if (context->getExtensions().lossyETCDecode)
724 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500725 context->handleError(InvalidOperation()
726 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400727 return false;
728 }
729 else
730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500731 context->handleError(InvalidEnum()
732 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400733 return false;
734 }
735 break;
736 case GL_DEPTH_COMPONENT:
737 case GL_DEPTH_COMPONENT16:
738 case GL_DEPTH_COMPONENT32_OES:
739 case GL_DEPTH_STENCIL_OES:
740 case GL_DEPTH24_STENCIL8_OES:
741 if (context->getExtensions().depthTextures)
742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500743 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400744 return false;
745 }
746 else
747 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500748 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400749 return false;
750 }
751 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500752 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400753 return false;
754 }
755 }
756
757 // If width or height is zero, it is a no-op. Return false without setting an error.
758 return (width > 0 && height > 0);
759}
760
761bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
762{
763 switch (cap)
764 {
765 // EXT_multisample_compatibility
766 case GL_MULTISAMPLE_EXT:
767 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
768 return context->getExtensions().multisampleCompatibility;
769
770 case GL_CULL_FACE:
771 case GL_POLYGON_OFFSET_FILL:
772 case GL_SAMPLE_ALPHA_TO_COVERAGE:
773 case GL_SAMPLE_COVERAGE:
774 case GL_SCISSOR_TEST:
775 case GL_STENCIL_TEST:
776 case GL_DEPTH_TEST:
777 case GL_BLEND:
778 case GL_DITHER:
779 return true;
780
781 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
782 case GL_RASTERIZER_DISCARD:
783 return (context->getClientMajorVersion() >= 3);
784
785 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
786 case GL_DEBUG_OUTPUT:
787 return context->getExtensions().debug;
788
789 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
790 return queryOnly && context->getExtensions().bindGeneratesResource;
791
792 case GL_CLIENT_ARRAYS_ANGLE:
793 return queryOnly && context->getExtensions().clientArrays;
794
795 case GL_FRAMEBUFFER_SRGB_EXT:
796 return context->getExtensions().sRGBWriteControl;
797
798 case GL_SAMPLE_MASK:
799 return context->getClientVersion() >= Version(3, 1);
800
Geoff Langb433e872017-10-05 14:01:47 -0400801 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400802 return queryOnly && context->getExtensions().robustResourceInitialization;
803
804 default:
805 return false;
806 }
807}
808
Geoff Langfc32e8b2017-05-31 14:16:59 -0400809// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
810// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400811bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400812{
813 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400814 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
815 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400816 {
817 return true;
818 }
819
820 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
821 if (c >= 9 && c <= 13)
822 {
823 return true;
824 }
825
826 return false;
827}
828
Geoff Langcab92ee2017-07-19 17:32:07 -0400829bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400830{
Geoff Langa71a98e2017-06-19 15:15:00 -0400831 for (size_t i = 0; i < len; i++)
832 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400833 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400834 {
835 return false;
836 }
837 }
838
839 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840}
841
Geoff Langcab92ee2017-07-19 17:32:07 -0400842bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
843{
844 enum class ParseState
845 {
846 // Have not seen an ASCII non-whitespace character yet on
847 // this line. Possible that we might see a preprocessor
848 // directive.
849 BEGINING_OF_LINE,
850
851 // Have seen at least one ASCII non-whitespace character
852 // on this line.
853 MIDDLE_OF_LINE,
854
855 // Handling a preprocessor directive. Passes through all
856 // characters up to the end of the line. Disables comment
857 // processing.
858 IN_PREPROCESSOR_DIRECTIVE,
859
860 // Handling a single-line comment. The comment text is
861 // replaced with a single space.
862 IN_SINGLE_LINE_COMMENT,
863
864 // Handling a multi-line comment. Newlines are passed
865 // through to preserve line numbers.
866 IN_MULTI_LINE_COMMENT
867 };
868
869 ParseState state = ParseState::BEGINING_OF_LINE;
870 size_t pos = 0;
871
872 while (pos < len)
873 {
874 char c = str[pos];
875 char next = pos + 1 < len ? str[pos + 1] : 0;
876
877 // Check for newlines
878 if (c == '\n' || c == '\r')
879 {
880 if (state != ParseState::IN_MULTI_LINE_COMMENT)
881 {
882 state = ParseState::BEGINING_OF_LINE;
883 }
884
885 pos++;
886 continue;
887 }
888
889 switch (state)
890 {
891 case ParseState::BEGINING_OF_LINE:
892 if (c == ' ')
893 {
894 // Maintain the BEGINING_OF_LINE state until a non-space is seen
895 pos++;
896 }
897 else if (c == '#')
898 {
899 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
900 pos++;
901 }
902 else
903 {
904 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
905 state = ParseState::MIDDLE_OF_LINE;
906 }
907 break;
908
909 case ParseState::MIDDLE_OF_LINE:
910 if (c == '/' && next == '/')
911 {
912 state = ParseState::IN_SINGLE_LINE_COMMENT;
913 pos++;
914 }
915 else if (c == '/' && next == '*')
916 {
917 state = ParseState::IN_MULTI_LINE_COMMENT;
918 pos++;
919 }
920 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
921 {
922 // Skip line continuation characters
923 }
924 else if (!IsValidESSLCharacter(c))
925 {
926 return false;
927 }
928 pos++;
929 break;
930
931 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700932 // Line-continuation characters may not be permitted.
933 // Otherwise, just pass it through. Do not parse comments in this state.
934 if (!lineContinuationAllowed && c == '\\')
935 {
936 return false;
937 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400938 pos++;
939 break;
940
941 case ParseState::IN_SINGLE_LINE_COMMENT:
942 // Line-continuation characters are processed before comment processing.
943 // Advance string if a new line character is immediately behind
944 // line-continuation character.
945 if (c == '\\' && (next == '\n' || next == '\r'))
946 {
947 pos++;
948 }
949 pos++;
950 break;
951
952 case ParseState::IN_MULTI_LINE_COMMENT:
953 if (c == '*' && next == '/')
954 {
955 state = ParseState::MIDDLE_OF_LINE;
956 pos++;
957 }
958 pos++;
959 break;
960 }
961 }
962
963 return true;
964}
965
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700966bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
967{
968 ASSERT(context->isWebGL());
969
970 // WebGL 1.0 [Section 6.16] GLSL Constructs
971 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
972 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
973 {
974 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
975 return false;
976 }
977
978 return true;
979}
980
981bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
982{
983 ASSERT(context->isWebGL());
984
985 if (context->isWebGL1() && length > 256)
986 {
987 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
988 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
989 // locations.
990 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
991
992 return false;
993 }
994 else if (length > 1024)
995 {
996 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
997 // uniform and attribute locations.
998 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
999 return false;
1000 }
1001
1002 return true;
1003}
1004
Jamie Madill007530e2017-12-28 14:27:04 -05001005bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1006{
1007 if (!context->getExtensions().pathRendering)
1008 {
1009 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1010 return false;
1011 }
1012
1013 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1014 {
1015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1016 return false;
1017 }
1018 return true;
1019}
Jamie Madillc29968b2016-01-20 11:17:23 -05001020} // anonymous namespace
1021
Geoff Langff5b2d52016-09-07 11:32:23 -04001022bool ValidateES2TexImageParameters(Context *context,
1023 GLenum target,
1024 GLint level,
1025 GLenum internalformat,
1026 bool isCompressed,
1027 bool isSubImage,
1028 GLint xoffset,
1029 GLint yoffset,
1030 GLsizei width,
1031 GLsizei height,
1032 GLint border,
1033 GLenum format,
1034 GLenum type,
1035 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001036 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037{
Jamie Madill6f38f822014-06-06 17:12:20 -04001038 if (!ValidTexture2DDestinationTarget(context, target))
1039 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001041 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001042 }
1043
Austin Kinross08528e12015-10-07 16:24:40 -07001044 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001045 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001046 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001047 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001048 }
1049
Brandon Jones6cad5662017-06-14 13:25:13 -07001050 if (!ValidMipLevel(context, target, level))
1051 {
1052 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1053 return false;
1054 }
1055
1056 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 std::numeric_limits<GLsizei>::max() - yoffset < height)
1058 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001059 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001060 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001061 }
1062
Geoff Lang6e898aa2017-06-02 11:17:26 -04001063 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1064 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1065 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1066 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1067 // case.
1068 bool nonEqualFormatsAllowed =
1069 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1070 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1071
1072 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001073 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001074 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001075 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076 }
1077
Geoff Langaae65a42014-05-26 12:43:44 -04001078 const gl::Caps &caps = context->getCaps();
1079
Geoff Langa9be0dc2014-12-17 12:34:40 -05001080 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001081 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05001082 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1083 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001085 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001086 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001087 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001088 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001089 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
1090 {
1091 ASSERT(level == 0);
1092 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1093 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1094 {
1095 context->handleError(InvalidValue());
1096 return false;
1097 }
1098 if (isCompressed)
1099 {
1100 context->handleError(InvalidEnum()
1101 << "Rectangle texture cannot have a compressed format.");
1102 return false;
1103 }
1104 }
Geoff Lang691e58c2014-12-19 17:03:25 -05001105 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -05001106 {
1107 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001109 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001110 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001111 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001112
Geoff Langa9be0dc2014-12-17 12:34:40 -05001113 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1114 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1115 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001116 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001117 return false;
1118 }
1119 }
1120 else
1121 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001122 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001123 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001124 }
1125
He Yunchaoced53ae2016-11-29 15:00:51 +08001126 gl::Texture *texture =
1127 context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001128 if (!texture)
1129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001131 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001132 }
1133
Geoff Langa9be0dc2014-12-17 12:34:40 -05001134 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001135 {
Geoff Langca271392017-04-05 12:30:00 -04001136 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1137 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001139 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001140 return false;
1141 }
1142
Geoff Langa9be0dc2014-12-17 12:34:40 -05001143 if (format != GL_NONE)
1144 {
Geoff Langca271392017-04-05 12:30:00 -04001145 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1146 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001147 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001149 return false;
1150 }
1151 }
1152
1153 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1154 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1155 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001156 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001157 return false;
1158 }
Geoff Langfb052642017-10-24 13:42:09 -04001159
1160 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallez336129f2017-10-17 15:55:40 -04001161 context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001162 {
1163 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1164 return false;
1165 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001166 }
1167 else
1168 {
Geoff Lang69cce582015-09-17 13:20:36 -04001169 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001171 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001172 return false;
1173 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174 }
1175
1176 // Verify zero border
1177 if (border != 0)
1178 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001179 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001180 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001181 }
1182
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001183 if (isCompressed)
1184 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001185 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001186 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1187 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001188 switch (actualInternalFormat)
1189 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001190 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1191 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1192 if (!context->getExtensions().textureCompressionDXT1)
1193 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001194 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001195 return false;
1196 }
1197 break;
1198 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001199 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001201 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001202 return false;
1203 }
1204 break;
1205 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1206 if (!context->getExtensions().textureCompressionDXT5)
1207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001208 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001209 return false;
1210 }
1211 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001212 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1213 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1214 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1215 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1216 if (!context->getExtensions().textureCompressionS3TCsRGB)
1217 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001218 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001219 return false;
1220 }
1221 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001222 case GL_ETC1_RGB8_OES:
1223 if (!context->getExtensions().compressedETC1RGB8Texture)
1224 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001226 return false;
1227 }
Geoff Lang86f81162017-10-30 15:10:45 -04001228 if (isSubImage)
1229 {
1230 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1231 return false;
1232 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001233 break;
1234 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001235 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1236 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1237 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1238 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001239 if (!context->getExtensions().lossyETCDecode)
1240 {
Geoff Lang86f81162017-10-30 15:10:45 -04001241 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001242 return false;
1243 }
1244 break;
1245 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001247 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001248 }
Geoff Lang966c9402017-04-18 12:38:27 -04001249
1250 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001251 {
Geoff Lang966c9402017-04-18 12:38:27 -04001252 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1253 height, texture->getWidth(target, level),
1254 texture->getHeight(target, level)))
1255 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001256 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001257 return false;
1258 }
1259
1260 if (format != actualInternalFormat)
1261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001262 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001263 return false;
1264 }
1265 }
1266 else
1267 {
1268 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1269 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001270 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001271 return false;
1272 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001273 }
1274 }
1275 else
1276 {
1277 // validate <type> by itself (used as secondary key below)
1278 switch (type)
1279 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001280 case GL_UNSIGNED_BYTE:
1281 case GL_UNSIGNED_SHORT_5_6_5:
1282 case GL_UNSIGNED_SHORT_4_4_4_4:
1283 case GL_UNSIGNED_SHORT_5_5_5_1:
1284 case GL_UNSIGNED_SHORT:
1285 case GL_UNSIGNED_INT:
1286 case GL_UNSIGNED_INT_24_8_OES:
1287 case GL_HALF_FLOAT_OES:
1288 case GL_FLOAT:
1289 break;
1290 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001291 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001292 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001293 }
1294
1295 // validate <format> + <type> combinations
1296 // - invalid <format> -> sets INVALID_ENUM
1297 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1298 switch (format)
1299 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001300 case GL_ALPHA:
1301 case GL_LUMINANCE:
1302 case GL_LUMINANCE_ALPHA:
1303 switch (type)
1304 {
1305 case GL_UNSIGNED_BYTE:
1306 case GL_FLOAT:
1307 case GL_HALF_FLOAT_OES:
1308 break;
1309 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001310 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001311 return false;
1312 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001313 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001314 case GL_RED:
1315 case GL_RG:
1316 if (!context->getExtensions().textureRG)
1317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001318 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001319 return false;
1320 }
1321 switch (type)
1322 {
1323 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001324 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001325 case GL_FLOAT:
1326 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001327 if (!context->getExtensions().textureFloat)
1328 {
1329 context->handleError(InvalidEnum());
1330 return false;
1331 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001332 break;
1333 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001334 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 return false;
1336 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001337 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 case GL_RGB:
1339 switch (type)
1340 {
1341 case GL_UNSIGNED_BYTE:
1342 case GL_UNSIGNED_SHORT_5_6_5:
1343 case GL_FLOAT:
1344 case GL_HALF_FLOAT_OES:
1345 break;
1346 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 return false;
1349 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001350 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 case GL_RGBA:
1352 switch (type)
1353 {
1354 case GL_UNSIGNED_BYTE:
1355 case GL_UNSIGNED_SHORT_4_4_4_4:
1356 case GL_UNSIGNED_SHORT_5_5_5_1:
1357 case GL_FLOAT:
1358 case GL_HALF_FLOAT_OES:
1359 break;
1360 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001361 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001362 return false;
1363 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001364 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001365 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001366 if (!context->getExtensions().textureFormatBGRA8888)
1367 {
1368 context->handleError(InvalidEnum());
1369 return false;
1370 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001371 switch (type)
1372 {
1373 case GL_UNSIGNED_BYTE:
1374 break;
1375 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 break;
1380 case GL_SRGB_EXT:
1381 case GL_SRGB_ALPHA_EXT:
1382 if (!context->getExtensions().sRGB)
1383 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001384 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001385 return false;
1386 }
1387 switch (type)
1388 {
1389 case GL_UNSIGNED_BYTE:
1390 break;
1391 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
1394 }
1395 break;
1396 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1397 // handled below
1398 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1399 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1400 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1401 break;
1402 case GL_DEPTH_COMPONENT:
1403 switch (type)
1404 {
1405 case GL_UNSIGNED_SHORT:
1406 case GL_UNSIGNED_INT:
1407 break;
1408 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001410 return false;
1411 }
1412 break;
1413 case GL_DEPTH_STENCIL_OES:
1414 switch (type)
1415 {
1416 case GL_UNSIGNED_INT_24_8_OES:
1417 break;
1418 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001419 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 return false;
1421 }
1422 break;
1423 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001424 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001425 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001426 }
1427
1428 switch (format)
1429 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001430 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1431 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1432 if (context->getExtensions().textureCompressionDXT1)
1433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001434 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001435 return false;
1436 }
1437 else
1438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001439 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001440 return false;
1441 }
1442 break;
1443 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1444 if (context->getExtensions().textureCompressionDXT3)
1445 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001446 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 return false;
1448 }
1449 else
1450 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001451 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001452 return false;
1453 }
1454 break;
1455 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1456 if (context->getExtensions().textureCompressionDXT5)
1457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001458 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001459 return false;
1460 }
1461 else
1462 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001463 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001464 return false;
1465 }
1466 break;
1467 case GL_ETC1_RGB8_OES:
1468 if (context->getExtensions().compressedETC1RGB8Texture)
1469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001470 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001471 return false;
1472 }
1473 else
1474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001475 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001476 return false;
1477 }
1478 break;
1479 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001480 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1481 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1482 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1483 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 if (context->getExtensions().lossyETCDecode)
1485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001486 context->handleError(InvalidOperation()
1487 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001488 return false;
1489 }
1490 else
1491 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001492 context->handleError(InvalidEnum()
1493 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001494 return false;
1495 }
1496 break;
1497 case GL_DEPTH_COMPONENT:
1498 case GL_DEPTH_STENCIL_OES:
1499 if (!context->getExtensions().depthTextures)
1500 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001501 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001502 return false;
1503 }
1504 if (target != GL_TEXTURE_2D)
1505 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001507 return false;
1508 }
1509 // OES_depth_texture supports loading depth data and multiple levels,
1510 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001511 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001512 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001513 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1514 return false;
1515 }
1516 if (level != 0)
1517 {
1518 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001519 return false;
1520 }
1521 break;
1522 default:
1523 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001524 }
1525
Geoff Lang6e898aa2017-06-02 11:17:26 -04001526 if (!isSubImage)
1527 {
1528 switch (internalformat)
1529 {
1530 case GL_RGBA32F:
1531 if (!context->getExtensions().colorBufferFloatRGBA)
1532 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001533 context->handleError(InvalidValue()
1534 << "Sized GL_RGBA32F internal format requires "
1535 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001536 return false;
1537 }
1538 if (type != GL_FLOAT)
1539 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001541 return false;
1542 }
1543 if (format != GL_RGBA)
1544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001545 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001546 return false;
1547 }
1548 break;
1549
1550 case GL_RGB32F:
1551 if (!context->getExtensions().colorBufferFloatRGB)
1552 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001553 context->handleError(InvalidValue()
1554 << "Sized GL_RGB32F internal format requires "
1555 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001556 return false;
1557 }
1558 if (type != GL_FLOAT)
1559 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001560 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001561 return false;
1562 }
1563 if (format != GL_RGB)
1564 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001566 return false;
1567 }
1568 break;
1569
1570 default:
1571 break;
1572 }
1573 }
1574
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001575 if (type == GL_FLOAT)
1576 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001577 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001578 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001579 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001580 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001581 }
1582 }
1583 else if (type == GL_HALF_FLOAT_OES)
1584 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001585 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001586 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001587 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001588 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001589 }
1590 }
1591 }
1592
Geoff Langdbcced82017-06-06 15:55:54 -04001593 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1594 if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001595 imageSize))
1596 {
1597 return false;
1598 }
1599
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001600 return true;
1601}
1602
He Yunchaoced53ae2016-11-29 15:00:51 +08001603bool ValidateES2TexStorageParameters(Context *context,
1604 GLenum target,
1605 GLsizei levels,
1606 GLenum internalformat,
1607 GLsizei width,
1608 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001609{
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001610 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
1611 target != GL_TEXTURE_RECTANGLE_ANGLE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001612 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001613 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001614 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001615 }
1616
1617 if (width < 1 || height < 1 || levels < 1)
1618 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001619 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001620 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001621 }
1622
1623 if (target == GL_TEXTURE_CUBE_MAP && width != height)
1624 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001625 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001626 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001627 }
1628
1629 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1630 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001631 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001632 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001633 }
1634
Geoff Langca271392017-04-05 12:30:00 -04001635 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001636 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001637 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001638 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001639 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001640 }
1641
Geoff Langaae65a42014-05-26 12:43:44 -04001642 const gl::Caps &caps = context->getCaps();
1643
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001644 switch (target)
1645 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001646 case GL_TEXTURE_2D:
1647 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1648 static_cast<GLuint>(height) > caps.max2DTextureSize)
1649 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001650 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001651 return false;
1652 }
1653 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001654 case GL_TEXTURE_RECTANGLE_ANGLE:
1655 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1656 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1657 {
1658 context->handleError(InvalidValue());
1659 return false;
1660 }
1661 if (formatInfo.compressed)
1662 {
1663 context->handleError(InvalidEnum()
1664 << "Rectangle texture cannot have a compressed format.");
1665 return false;
1666 }
1667 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001668 case GL_TEXTURE_CUBE_MAP:
1669 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1670 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1671 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001672 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001673 return false;
1674 }
1675 break;
1676 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001678 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001679 }
1680
Geoff Langc0b9ef42014-07-02 10:02:37 -04001681 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 {
1683 if (!gl::isPow2(width) || !gl::isPow2(height))
1684 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001685 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001686 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001687 }
1688 }
1689
1690 switch (internalformat)
1691 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001692 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1693 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1694 if (!context->getExtensions().textureCompressionDXT1)
1695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001696 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001697 return false;
1698 }
1699 break;
1700 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1701 if (!context->getExtensions().textureCompressionDXT3)
1702 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001703 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 return false;
1705 }
1706 break;
1707 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1708 if (!context->getExtensions().textureCompressionDXT5)
1709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001710 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001711 return false;
1712 }
1713 break;
1714 case GL_ETC1_RGB8_OES:
1715 if (!context->getExtensions().compressedETC1RGB8Texture)
1716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001717 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001718 return false;
1719 }
1720 break;
1721 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001722 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1723 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1724 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1725 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 if (!context->getExtensions().lossyETCDecode)
1727 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001728 context->handleError(InvalidEnum()
1729 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001730 return false;
1731 }
1732 break;
1733 case GL_RGBA32F_EXT:
1734 case GL_RGB32F_EXT:
1735 case GL_ALPHA32F_EXT:
1736 case GL_LUMINANCE32F_EXT:
1737 case GL_LUMINANCE_ALPHA32F_EXT:
1738 if (!context->getExtensions().textureFloat)
1739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001740 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001741 return false;
1742 }
1743 break;
1744 case GL_RGBA16F_EXT:
1745 case GL_RGB16F_EXT:
1746 case GL_ALPHA16F_EXT:
1747 case GL_LUMINANCE16F_EXT:
1748 case GL_LUMINANCE_ALPHA16F_EXT:
1749 if (!context->getExtensions().textureHalfFloat)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001752 return false;
1753 }
1754 break;
1755 case GL_R8_EXT:
1756 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG)
1758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001760 return false;
1761 }
1762 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001763 case GL_R16F_EXT:
1764 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001765 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001767 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001768 return false;
1769 }
1770 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 case GL_R32F_EXT:
1772 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001773 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001775 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001776 return false;
1777 }
1778 break;
1779 case GL_DEPTH_COMPONENT16:
1780 case GL_DEPTH_COMPONENT32_OES:
1781 case GL_DEPTH24_STENCIL8_OES:
1782 if (!context->getExtensions().depthTextures)
1783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001784 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001785 return false;
1786 }
1787 if (target != GL_TEXTURE_2D)
1788 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001789 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001790 return false;
1791 }
1792 // ANGLE_depth_texture only supports 1-level textures
1793 if (levels != 1)
1794 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001795 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001796 return false;
1797 }
1798 break;
1799 default:
1800 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001801 }
1802
Geoff Lang691e58c2014-12-19 17:03:25 -05001803 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001804 if (!texture || texture->id() == 0)
1805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001806 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001807 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001808 }
1809
Geoff Lang69cce582015-09-17 13:20:36 -04001810 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001812 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001813 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001814 }
1815
1816 return true;
1817}
1818
He Yunchaoced53ae2016-11-29 15:00:51 +08001819bool ValidateDiscardFramebufferEXT(Context *context,
1820 GLenum target,
1821 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001822 const GLenum *attachments)
1823{
Jamie Madillc29968b2016-01-20 11:17:23 -05001824 if (!context->getExtensions().discardFramebuffer)
1825 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001826 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001827 return false;
1828 }
1829
Austin Kinross08332632015-05-05 13:35:47 -07001830 bool defaultFramebuffer = false;
1831
1832 switch (target)
1833 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001834 case GL_FRAMEBUFFER:
1835 defaultFramebuffer =
1836 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1837 break;
1838 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001839 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001840 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001841 }
1842
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1844 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001845}
1846
Austin Kinrossbc781f32015-10-26 09:27:38 -07001847bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1848{
1849 if (!context->getExtensions().vertexArrayObject)
1850 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001851 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852 return false;
1853 }
1854
1855 return ValidateBindVertexArrayBase(context, array);
1856}
1857
Jamie Madilld7576732017-08-26 18:49:50 -04001858bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859{
1860 if (!context->getExtensions().vertexArrayObject)
1861 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001862 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863 return false;
1864 }
1865
Olli Etuaho41997e72016-03-10 13:38:39 +02001866 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001867}
1868
Jamie Madilld7576732017-08-26 18:49:50 -04001869bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870{
1871 if (!context->getExtensions().vertexArrayObject)
1872 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001873 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001874 return false;
1875 }
1876
Olli Etuaho41997e72016-03-10 13:38:39 +02001877 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001878}
1879
Jamie Madilld7576732017-08-26 18:49:50 -04001880bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001881{
1882 if (!context->getExtensions().vertexArrayObject)
1883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001884 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001885 return false;
1886 }
1887
1888 return true;
1889}
Geoff Langc5629752015-12-07 16:29:04 -05001890
1891bool ValidateProgramBinaryOES(Context *context,
1892 GLuint program,
1893 GLenum binaryFormat,
1894 const void *binary,
1895 GLint length)
1896{
1897 if (!context->getExtensions().getProgramBinary)
1898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001899 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001900 return false;
1901 }
1902
1903 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1904}
1905
1906bool ValidateGetProgramBinaryOES(Context *context,
1907 GLuint program,
1908 GLsizei bufSize,
1909 GLsizei *length,
1910 GLenum *binaryFormat,
1911 void *binary)
1912{
1913 if (!context->getExtensions().getProgramBinary)
1914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001915 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001916 return false;
1917 }
1918
1919 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1920}
Geoff Lange102fee2015-12-10 11:23:30 -05001921
Geoff Lang70d0f492015-12-10 17:45:46 -05001922static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1923{
1924 switch (source)
1925 {
1926 case GL_DEBUG_SOURCE_API:
1927 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1928 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1929 case GL_DEBUG_SOURCE_OTHER:
1930 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1931 return !mustBeThirdPartyOrApplication;
1932
1933 case GL_DEBUG_SOURCE_THIRD_PARTY:
1934 case GL_DEBUG_SOURCE_APPLICATION:
1935 return true;
1936
1937 default:
1938 return false;
1939 }
1940}
1941
1942static bool ValidDebugType(GLenum type)
1943{
1944 switch (type)
1945 {
1946 case GL_DEBUG_TYPE_ERROR:
1947 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1948 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1949 case GL_DEBUG_TYPE_PERFORMANCE:
1950 case GL_DEBUG_TYPE_PORTABILITY:
1951 case GL_DEBUG_TYPE_OTHER:
1952 case GL_DEBUG_TYPE_MARKER:
1953 case GL_DEBUG_TYPE_PUSH_GROUP:
1954 case GL_DEBUG_TYPE_POP_GROUP:
1955 return true;
1956
1957 default:
1958 return false;
1959 }
1960}
1961
1962static bool ValidDebugSeverity(GLenum severity)
1963{
1964 switch (severity)
1965 {
1966 case GL_DEBUG_SEVERITY_HIGH:
1967 case GL_DEBUG_SEVERITY_MEDIUM:
1968 case GL_DEBUG_SEVERITY_LOW:
1969 case GL_DEBUG_SEVERITY_NOTIFICATION:
1970 return true;
1971
1972 default:
1973 return false;
1974 }
1975}
1976
Geoff Lange102fee2015-12-10 11:23:30 -05001977bool ValidateDebugMessageControlKHR(Context *context,
1978 GLenum source,
1979 GLenum type,
1980 GLenum severity,
1981 GLsizei count,
1982 const GLuint *ids,
1983 GLboolean enabled)
1984{
1985 if (!context->getExtensions().debug)
1986 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001987 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001988 return false;
1989 }
1990
Geoff Lang70d0f492015-12-10 17:45:46 -05001991 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001994 return false;
1995 }
1996
1997 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1998 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001999 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002000 return false;
2001 }
2002
2003 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2004 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002005 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002006 return false;
2007 }
2008
2009 if (count > 0)
2010 {
2011 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2012 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002013 context->handleError(
2014 InvalidOperation()
2015 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018
2019 if (severity != GL_DONT_CARE)
2020 {
Jamie Madill437fa652016-05-03 15:13:24 -04002021 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002022 InvalidOperation()
2023 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002024 return false;
2025 }
2026 }
2027
Geoff Lange102fee2015-12-10 11:23:30 -05002028 return true;
2029}
2030
2031bool ValidateDebugMessageInsertKHR(Context *context,
2032 GLenum source,
2033 GLenum type,
2034 GLuint id,
2035 GLenum severity,
2036 GLsizei length,
2037 const GLchar *buf)
2038{
2039 if (!context->getExtensions().debug)
2040 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002041 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002042 return false;
2043 }
2044
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002045 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002046 {
2047 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2048 // not generate an error.
2049 return false;
2050 }
2051
2052 if (!ValidDebugSeverity(severity))
2053 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002054 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002055 return false;
2056 }
2057
2058 if (!ValidDebugType(type))
2059 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002060 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002061 return false;
2062 }
2063
2064 if (!ValidDebugSource(source, true))
2065 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002066 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002067 return false;
2068 }
2069
2070 size_t messageLength = (length < 0) ? strlen(buf) : length;
2071 if (messageLength > context->getExtensions().maxDebugMessageLength)
2072 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002073 context->handleError(InvalidValue()
2074 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002075 return false;
2076 }
2077
Geoff Lange102fee2015-12-10 11:23:30 -05002078 return true;
2079}
2080
2081bool ValidateDebugMessageCallbackKHR(Context *context,
2082 GLDEBUGPROCKHR callback,
2083 const void *userParam)
2084{
2085 if (!context->getExtensions().debug)
2086 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002087 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002088 return false;
2089 }
2090
Geoff Lange102fee2015-12-10 11:23:30 -05002091 return true;
2092}
2093
2094bool ValidateGetDebugMessageLogKHR(Context *context,
2095 GLuint count,
2096 GLsizei bufSize,
2097 GLenum *sources,
2098 GLenum *types,
2099 GLuint *ids,
2100 GLenum *severities,
2101 GLsizei *lengths,
2102 GLchar *messageLog)
2103{
2104 if (!context->getExtensions().debug)
2105 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002106 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002107 return false;
2108 }
2109
Geoff Lang70d0f492015-12-10 17:45:46 -05002110 if (bufSize < 0 && messageLog != nullptr)
2111 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002112 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002113 return false;
2114 }
2115
Geoff Lange102fee2015-12-10 11:23:30 -05002116 return true;
2117}
2118
2119bool ValidatePushDebugGroupKHR(Context *context,
2120 GLenum source,
2121 GLuint id,
2122 GLsizei length,
2123 const GLchar *message)
2124{
2125 if (!context->getExtensions().debug)
2126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002128 return false;
2129 }
2130
Geoff Lang70d0f492015-12-10 17:45:46 -05002131 if (!ValidDebugSource(source, true))
2132 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002133 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136
2137 size_t messageLength = (length < 0) ? strlen(message) : length;
2138 if (messageLength > context->getExtensions().maxDebugMessageLength)
2139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002140 context->handleError(InvalidValue()
2141 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002142 return false;
2143 }
2144
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002145 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002146 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002148 context
2149 ->handleError(StackOverflow()
2150 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002151 return false;
2152 }
2153
Geoff Lange102fee2015-12-10 11:23:30 -05002154 return true;
2155}
2156
2157bool ValidatePopDebugGroupKHR(Context *context)
2158{
2159 if (!context->getExtensions().debug)
2160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002162 return false;
2163 }
2164
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002165 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002166 if (currentStackSize <= 1)
2167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002168 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 return false;
2170 }
2171
2172 return true;
2173}
2174
2175static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2176{
2177 switch (identifier)
2178 {
2179 case GL_BUFFER:
2180 if (context->getBuffer(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_SHADER:
2188 if (context->getShader(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_PROGRAM:
2196 if (context->getProgram(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_VERTEX_ARRAY:
2204 if (context->getVertexArray(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_QUERY:
2212 if (context->getQuery(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_TRANSFORM_FEEDBACK:
2220 if (context->getTransformFeedback(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_SAMPLER:
2228 if (context->getSampler(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_TEXTURE:
2236 if (context->getTexture(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 case GL_RENDERBUFFER:
2244 if (context->getRenderbuffer(name) == nullptr)
2245 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249 return true;
2250
2251 case GL_FRAMEBUFFER:
2252 if (context->getFramebuffer(name) == nullptr)
2253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002254 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002255 return false;
2256 }
2257 return true;
2258
2259 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002260 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002261 return false;
2262 }
Geoff Lange102fee2015-12-10 11:23:30 -05002263}
2264
Martin Radev9d901792016-07-15 15:58:58 +03002265static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2266{
2267 size_t labelLength = 0;
2268
2269 if (length < 0)
2270 {
2271 if (label != nullptr)
2272 {
2273 labelLength = strlen(label);
2274 }
2275 }
2276 else
2277 {
2278 labelLength = static_cast<size_t>(length);
2279 }
2280
2281 if (labelLength > context->getExtensions().maxLabelLength)
2282 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002283 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002284 return false;
2285 }
2286
2287 return true;
2288}
2289
Geoff Lange102fee2015-12-10 11:23:30 -05002290bool ValidateObjectLabelKHR(Context *context,
2291 GLenum identifier,
2292 GLuint name,
2293 GLsizei length,
2294 const GLchar *label)
2295{
2296 if (!context->getExtensions().debug)
2297 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002298 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002299 return false;
2300 }
2301
Geoff Lang70d0f492015-12-10 17:45:46 -05002302 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2303 {
2304 return false;
2305 }
2306
Martin Radev9d901792016-07-15 15:58:58 +03002307 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002308 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002309 return false;
2310 }
2311
Geoff Lange102fee2015-12-10 11:23:30 -05002312 return true;
2313}
2314
2315bool ValidateGetObjectLabelKHR(Context *context,
2316 GLenum identifier,
2317 GLuint name,
2318 GLsizei bufSize,
2319 GLsizei *length,
2320 GLchar *label)
2321{
2322 if (!context->getExtensions().debug)
2323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002324 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002325 return false;
2326 }
2327
Geoff Lang70d0f492015-12-10 17:45:46 -05002328 if (bufSize < 0)
2329 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002330 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 return false;
2332 }
2333
2334 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2335 {
2336 return false;
2337 }
2338
Martin Radev9d901792016-07-15 15:58:58 +03002339 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002340}
2341
2342static bool ValidateObjectPtrName(Context *context, const void *ptr)
2343{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002344 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002345 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002346 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002347 return false;
2348 }
2349
Geoff Lange102fee2015-12-10 11:23:30 -05002350 return true;
2351}
2352
2353bool ValidateObjectPtrLabelKHR(Context *context,
2354 const void *ptr,
2355 GLsizei length,
2356 const GLchar *label)
2357{
2358 if (!context->getExtensions().debug)
2359 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002361 return false;
2362 }
2363
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 if (!ValidateObjectPtrName(context, ptr))
2365 {
2366 return false;
2367 }
2368
Martin Radev9d901792016-07-15 15:58:58 +03002369 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002370 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002371 return false;
2372 }
2373
Geoff Lange102fee2015-12-10 11:23:30 -05002374 return true;
2375}
2376
2377bool ValidateGetObjectPtrLabelKHR(Context *context,
2378 const void *ptr,
2379 GLsizei bufSize,
2380 GLsizei *length,
2381 GLchar *label)
2382{
2383 if (!context->getExtensions().debug)
2384 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002386 return false;
2387 }
2388
Geoff Lang70d0f492015-12-10 17:45:46 -05002389 if (bufSize < 0)
2390 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002391 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002392 return false;
2393 }
2394
2395 if (!ValidateObjectPtrName(context, ptr))
2396 {
2397 return false;
2398 }
2399
Martin Radev9d901792016-07-15 15:58:58 +03002400 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002401}
2402
2403bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2404{
2405 if (!context->getExtensions().debug)
2406 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002407 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002408 return false;
2409 }
2410
Geoff Lang70d0f492015-12-10 17:45:46 -05002411 // TODO: represent this in Context::getQueryParameterInfo.
2412 switch (pname)
2413 {
2414 case GL_DEBUG_CALLBACK_FUNCTION:
2415 case GL_DEBUG_CALLBACK_USER_PARAM:
2416 break;
2417
2418 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002419 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002420 return false;
2421 }
2422
Geoff Lange102fee2015-12-10 11:23:30 -05002423 return true;
2424}
Jamie Madillc29968b2016-01-20 11:17:23 -05002425
2426bool ValidateBlitFramebufferANGLE(Context *context,
2427 GLint srcX0,
2428 GLint srcY0,
2429 GLint srcX1,
2430 GLint srcY1,
2431 GLint dstX0,
2432 GLint dstY0,
2433 GLint dstX1,
2434 GLint dstY1,
2435 GLbitfield mask,
2436 GLenum filter)
2437{
2438 if (!context->getExtensions().framebufferBlit)
2439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002440 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002441 return false;
2442 }
2443
2444 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2445 {
2446 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidOperation() << "Scaling and flipping in "
2448 "BlitFramebufferANGLE not supported by this "
2449 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002450 return false;
2451 }
2452
2453 if (filter == GL_LINEAR)
2454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002455 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002456 return false;
2457 }
2458
Jamie Madill51f40ec2016-06-15 14:06:00 -04002459 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2460 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002461
2462 if (mask & GL_COLOR_BUFFER_BIT)
2463 {
2464 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2465 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2466
2467 if (readColorAttachment && drawColorAttachment)
2468 {
2469 if (!(readColorAttachment->type() == GL_TEXTURE &&
2470 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2471 readColorAttachment->type() != GL_RENDERBUFFER &&
2472 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002474 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002475 return false;
2476 }
2477
Geoff Langa15472a2015-08-11 11:48:03 -04002478 for (size_t drawbufferIdx = 0;
2479 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002480 {
Geoff Langa15472a2015-08-11 11:48:03 -04002481 const FramebufferAttachment *attachment =
2482 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2483 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002485 if (!(attachment->type() == GL_TEXTURE &&
2486 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2487 attachment->type() != GL_RENDERBUFFER &&
2488 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002490 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 return false;
2492 }
2493
2494 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002495 if (!Format::EquivalentForBlit(attachment->getFormat(),
2496 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002497 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002498 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002499 return false;
2500 }
2501 }
2502 }
2503
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002504 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2506 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2507 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002508 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002509 return false;
2510 }
2511 }
2512 }
2513
2514 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2515 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2516 for (size_t i = 0; i < 2; i++)
2517 {
2518 if (mask & masks[i])
2519 {
2520 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002521 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002522 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002523 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002524
2525 if (readBuffer && drawBuffer)
2526 {
2527 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2528 dstX0, dstY0, dstX1, dstY1))
2529 {
2530 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002531 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2532 "stencil blits are supported by "
2533 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002534 return false;
2535 }
2536
2537 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002539 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 return false;
2541 }
2542 }
2543 }
2544 }
2545
2546 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2547 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002548}
Jamie Madillc29968b2016-01-20 11:17:23 -05002549
2550bool ValidateClear(ValidationContext *context, GLbitfield mask)
2551{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002552 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002553 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002555 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002556 return false;
2557 }
2558
2559 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2560 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002561 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002562 return false;
2563 }
2564
Geoff Lang76e65652017-03-27 14:58:02 -04002565 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2566 {
2567 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2568 GL_SIGNED_NORMALIZED};
2569
Corentin Wallez59c41592017-07-11 13:19:54 -04002570 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002571 drawBufferIdx++)
2572 {
2573 if (!ValidateWebGLFramebufferAttachmentClearType(
2574 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2575 {
2576 return false;
2577 }
2578 }
2579 }
2580
Jamie Madillc29968b2016-01-20 11:17:23 -05002581 return true;
2582}
2583
2584bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2585{
2586 if (!context->getExtensions().drawBuffers)
2587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002588 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 return false;
2590 }
2591
2592 return ValidateDrawBuffersBase(context, n, bufs);
2593}
2594
Jamie Madill73a84962016-02-12 09:27:23 -05002595bool ValidateTexImage2D(Context *context,
2596 GLenum target,
2597 GLint level,
2598 GLint internalformat,
2599 GLsizei width,
2600 GLsizei height,
2601 GLint border,
2602 GLenum format,
2603 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002604 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002605{
Martin Radev1be913c2016-07-11 17:59:16 +03002606 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002607 {
2608 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002609 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002610 }
2611
Martin Radev1be913c2016-07-11 17:59:16 +03002612 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002613 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002614 0, 0, width, height, 1, border, format, type, -1,
2615 pixels);
2616}
2617
2618bool ValidateTexImage2DRobust(Context *context,
2619 GLenum target,
2620 GLint level,
2621 GLint internalformat,
2622 GLsizei width,
2623 GLsizei height,
2624 GLint border,
2625 GLenum format,
2626 GLenum type,
2627 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002628 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002629{
2630 if (!ValidateRobustEntryPoint(context, bufSize))
2631 {
2632 return false;
2633 }
2634
2635 if (context->getClientMajorVersion() < 3)
2636 {
2637 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2638 0, 0, width, height, border, format, type, bufSize,
2639 pixels);
2640 }
2641
2642 ASSERT(context->getClientMajorVersion() >= 3);
2643 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2644 0, 0, width, height, 1, border, format, type, bufSize,
2645 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002646}
2647
2648bool ValidateTexSubImage2D(Context *context,
2649 GLenum target,
2650 GLint level,
2651 GLint xoffset,
2652 GLint yoffset,
2653 GLsizei width,
2654 GLsizei height,
2655 GLenum format,
2656 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002657 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002658{
2659
Martin Radev1be913c2016-07-11 17:59:16 +03002660 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002661 {
2662 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002663 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002664 }
2665
Martin Radev1be913c2016-07-11 17:59:16 +03002666 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002667 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002668 yoffset, 0, width, height, 1, 0, format, type, -1,
2669 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002670}
2671
Geoff Langc52f6f12016-10-14 10:18:00 -04002672bool ValidateTexSubImage2DRobustANGLE(Context *context,
2673 GLenum target,
2674 GLint level,
2675 GLint xoffset,
2676 GLint yoffset,
2677 GLsizei width,
2678 GLsizei height,
2679 GLenum format,
2680 GLenum type,
2681 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002682 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002683{
2684 if (!ValidateRobustEntryPoint(context, bufSize))
2685 {
2686 return false;
2687 }
2688
2689 if (context->getClientMajorVersion() < 3)
2690 {
2691 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2692 yoffset, width, height, 0, format, type, bufSize,
2693 pixels);
2694 }
2695
2696 ASSERT(context->getClientMajorVersion() >= 3);
2697 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2698 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2699 pixels);
2700}
2701
Jamie Madill73a84962016-02-12 09:27:23 -05002702bool ValidateCompressedTexImage2D(Context *context,
2703 GLenum target,
2704 GLint level,
2705 GLenum internalformat,
2706 GLsizei width,
2707 GLsizei height,
2708 GLint border,
2709 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002710 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002711{
Martin Radev1be913c2016-07-11 17:59:16 +03002712 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002713 {
2714 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002715 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002716 {
2717 return false;
2718 }
2719 }
2720 else
2721 {
Martin Radev1be913c2016-07-11 17:59:16 +03002722 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002723 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002724 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002725 data))
2726 {
2727 return false;
2728 }
2729 }
2730
Geoff Langca271392017-04-05 12:30:00 -04002731 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002732 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002733 if (blockSizeOrErr.isError())
2734 {
2735 context->handleError(blockSizeOrErr.getError());
2736 return false;
2737 }
2738
2739 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002740 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002741 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002742 return false;
2743 }
2744
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002745 if (target == GL_TEXTURE_RECTANGLE_ANGLE)
2746 {
2747 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2748 return false;
2749 }
2750
Jamie Madill73a84962016-02-12 09:27:23 -05002751 return true;
2752}
2753
Corentin Wallezb2931602017-04-11 15:58:57 -04002754bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
2755 GLenum target,
2756 GLint level,
2757 GLenum internalformat,
2758 GLsizei width,
2759 GLsizei height,
2760 GLint border,
2761 GLsizei imageSize,
2762 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002763 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002764{
2765 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2766 {
2767 return false;
2768 }
2769
2770 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2771 border, imageSize, data);
2772}
2773bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
2774 GLenum target,
2775 GLint level,
2776 GLint xoffset,
2777 GLint yoffset,
2778 GLsizei width,
2779 GLsizei height,
2780 GLenum format,
2781 GLsizei imageSize,
2782 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002783 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002784{
2785 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2786 {
2787 return false;
2788 }
2789
2790 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2791 format, imageSize, data);
2792}
2793
Jamie Madill73a84962016-02-12 09:27:23 -05002794bool ValidateCompressedTexSubImage2D(Context *context,
2795 GLenum target,
2796 GLint level,
2797 GLint xoffset,
2798 GLint yoffset,
2799 GLsizei width,
2800 GLsizei height,
2801 GLenum format,
2802 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002803 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002804{
Martin Radev1be913c2016-07-11 17:59:16 +03002805 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002806 {
2807 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002808 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002809 {
2810 return false;
2811 }
2812 }
2813 else
2814 {
Martin Radev1be913c2016-07-11 17:59:16 +03002815 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002816 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002817 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002818 data))
2819 {
2820 return false;
2821 }
2822 }
2823
Geoff Langca271392017-04-05 12:30:00 -04002824 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002825 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002826 if (blockSizeOrErr.isError())
2827 {
2828 context->handleError(blockSizeOrErr.getError());
2829 return false;
2830 }
2831
2832 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002834 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002835 return false;
2836 }
2837
2838 return true;
2839}
2840
Corentin Wallez336129f2017-10-17 15:55:40 -04002841bool ValidateGetBufferPointervOES(Context *context,
2842 BufferBinding target,
2843 GLenum pname,
2844 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002845{
Geoff Lang496c02d2016-10-20 11:38:11 -07002846 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002847}
2848
Corentin Wallez336129f2017-10-17 15:55:40 -04002849bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002850{
2851 if (!context->getExtensions().mapBuffer)
2852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002853 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002854 return false;
2855 }
2856
Corentin Walleze4477002017-12-01 14:39:58 -05002857 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002858 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002859 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002860 return false;
2861 }
2862
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002863 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002864
2865 if (buffer == nullptr)
2866 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002867 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002868 return false;
2869 }
2870
2871 if (access != GL_WRITE_ONLY_OES)
2872 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002873 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002874 return false;
2875 }
2876
2877 if (buffer->isMapped())
2878 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002879 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002880 return false;
2881 }
2882
Geoff Lang79f71042017-08-14 16:43:43 -04002883 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002884}
2885
Corentin Wallez336129f2017-10-17 15:55:40 -04002886bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002887{
2888 if (!context->getExtensions().mapBuffer)
2889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002890 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002891 return false;
2892 }
2893
2894 return ValidateUnmapBufferBase(context, target);
2895}
2896
2897bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002898 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002899 GLintptr offset,
2900 GLsizeiptr length,
2901 GLbitfield access)
2902{
2903 if (!context->getExtensions().mapBufferRange)
2904 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002905 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002906 return false;
2907 }
2908
2909 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2910}
2911
Corentin Wallez336129f2017-10-17 15:55:40 -04002912bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002913{
2914 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2915 ASSERT(buffer != nullptr);
2916
2917 // Check if this buffer is currently being used as a transform feedback output buffer
2918 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2919 if (transformFeedback != nullptr && transformFeedback->isActive())
2920 {
2921 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2922 {
2923 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2924 if (transformFeedbackBuffer.get() == buffer)
2925 {
2926 context->handleError(InvalidOperation()
2927 << "Buffer is currently bound for transform feedback.");
2928 return false;
2929 }
2930 }
2931 }
2932
2933 return true;
2934}
2935
Olli Etuaho4f667482016-03-30 15:56:35 +03002936bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002937 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002938 GLintptr offset,
2939 GLsizeiptr length)
2940{
2941 if (!context->getExtensions().mapBufferRange)
2942 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002943 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002944 return false;
2945 }
2946
2947 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2948}
2949
Ian Ewell54f87462016-03-10 13:47:21 -05002950bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
2951{
2952 Texture *textureObject = context->getTexture(texture);
2953 if (textureObject && textureObject->getTarget() != target && texture != 0)
2954 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002955 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002956 return false;
2957 }
2958
Geoff Langf41a7152016-09-19 15:11:17 -04002959 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2960 !context->isTextureGenerated(texture))
2961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002962 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002963 return false;
2964 }
2965
Ian Ewell54f87462016-03-10 13:47:21 -05002966 switch (target)
2967 {
2968 case GL_TEXTURE_2D:
2969 case GL_TEXTURE_CUBE_MAP:
2970 break;
2971
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002972 case GL_TEXTURE_RECTANGLE_ANGLE:
2973 if (!context->getExtensions().textureRectangle)
2974 {
2975 context->handleError(InvalidEnum()
2976 << "Context does not support GL_ANGLE_texture_rectangle");
2977 return false;
2978 }
2979 break;
2980
Ian Ewell54f87462016-03-10 13:47:21 -05002981 case GL_TEXTURE_3D:
2982 case GL_TEXTURE_2D_ARRAY:
Martin Radev1be913c2016-07-11 17:59:16 +03002983 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002986 return false;
2987 }
2988 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002989
2990 case GL_TEXTURE_2D_MULTISAMPLE:
2991 if (context->getClientVersion() < Version(3, 1))
2992 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002994 return false;
2995 }
Geoff Lang3b573612016-10-31 14:08:10 -04002996 break;
2997
Ian Ewell54f87462016-03-10 13:47:21 -05002998 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002999 if (!context->getExtensions().eglImageExternal &&
3000 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05003001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003002 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05003003 return false;
3004 }
3005 break;
3006 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003007 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05003008 return false;
3009 }
3010
3011 return true;
3012}
3013
Geoff Langd8605522016-04-13 10:19:12 -04003014bool ValidateBindUniformLocationCHROMIUM(Context *context,
3015 GLuint program,
3016 GLint location,
3017 const GLchar *name)
3018{
3019 if (!context->getExtensions().bindUniformLocation)
3020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003021 context->handleError(InvalidOperation()
3022 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003023 return false;
3024 }
3025
3026 Program *programObject = GetValidProgram(context, program);
3027 if (!programObject)
3028 {
3029 return false;
3030 }
3031
3032 if (location < 0)
3033 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003034 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003035 return false;
3036 }
3037
3038 const Caps &caps = context->getCaps();
3039 if (static_cast<size_t>(location) >=
3040 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3041 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003042 context->handleError(InvalidValue() << "Location must be less than "
3043 "(MAX_VERTEX_UNIFORM_VECTORS + "
3044 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003045 return false;
3046 }
3047
Geoff Langfc32e8b2017-05-31 14:16:59 -04003048 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3049 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003050 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003051 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003052 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003053 return false;
3054 }
3055
Geoff Langd8605522016-04-13 10:19:12 -04003056 if (strncmp(name, "gl_", 3) == 0)
3057 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003058 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003059 return false;
3060 }
3061
3062 return true;
3063}
3064
Jamie Madille2e406c2016-06-02 13:04:10 -04003065bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003066{
3067 if (!context->getExtensions().framebufferMixedSamples)
3068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003069 context->handleError(InvalidOperation()
3070 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003071 return false;
3072 }
3073 switch (components)
3074 {
3075 case GL_RGB:
3076 case GL_RGBA:
3077 case GL_ALPHA:
3078 case GL_NONE:
3079 break;
3080 default:
3081 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003082 InvalidEnum()
3083 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003084 return false;
3085 }
3086
3087 return true;
3088}
3089
Sami Väisänene45e53b2016-05-25 10:36:04 +03003090// CHROMIUM_path_rendering
3091
Jamie Madill007530e2017-12-28 14:27:04 -05003092bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003093{
Jamie Madill007530e2017-12-28 14:27:04 -05003094 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003095 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003096 return false;
3097 }
Jamie Madill007530e2017-12-28 14:27:04 -05003098
Sami Väisänene45e53b2016-05-25 10:36:04 +03003099 if (matrix == nullptr)
3100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003101 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102 return false;
3103 }
Jamie Madill007530e2017-12-28 14:27:04 -05003104
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 return true;
3106}
3107
Jamie Madill007530e2017-12-28 14:27:04 -05003108bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003109{
Jamie Madill007530e2017-12-28 14:27:04 -05003110 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003111}
3112
Jamie Madill007530e2017-12-28 14:27:04 -05003113bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003114{
3115 if (!context->getExtensions().pathRendering)
3116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003117 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003118 return false;
3119 }
3120
3121 // range = 0 is undefined in NV_path_rendering.
3122 // we add stricter semantic check here and require a non zero positive range.
3123 if (range <= 0)
3124 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003125 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126 return false;
3127 }
3128
3129 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003131 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003132 return false;
3133 }
3134
3135 return true;
3136}
3137
Jamie Madill007530e2017-12-28 14:27:04 -05003138bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003139{
3140 if (!context->getExtensions().pathRendering)
3141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003142 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return false;
3144 }
3145
3146 // range = 0 is undefined in NV_path_rendering.
3147 // we add stricter semantic check here and require a non zero positive range.
3148 if (range <= 0)
3149 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003150 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003151 return false;
3152 }
3153
3154 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3155 checkedRange += range;
3156
3157 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3158 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003159 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003160 return false;
3161 }
3162 return true;
3163}
3164
Jamie Madill007530e2017-12-28 14:27:04 -05003165bool ValidatePathCommandsCHROMIUM(Context *context,
3166 GLuint path,
3167 GLsizei numCommands,
3168 const GLubyte *commands,
3169 GLsizei numCoords,
3170 GLenum coordType,
3171 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003172{
3173 if (!context->getExtensions().pathRendering)
3174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003175 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003176 return false;
3177 }
3178 if (!context->hasPath(path))
3179 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003180 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183
3184 if (numCommands < 0)
3185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003186 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003187 return false;
3188 }
3189 else if (numCommands > 0)
3190 {
3191 if (!commands)
3192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003193 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 return false;
3195 }
3196 }
3197
3198 if (numCoords < 0)
3199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003200 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003201 return false;
3202 }
3203 else if (numCoords > 0)
3204 {
3205 if (!coords)
3206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003207 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208 return false;
3209 }
3210 }
3211
3212 std::uint32_t coordTypeSize = 0;
3213 switch (coordType)
3214 {
3215 case GL_BYTE:
3216 coordTypeSize = sizeof(GLbyte);
3217 break;
3218
3219 case GL_UNSIGNED_BYTE:
3220 coordTypeSize = sizeof(GLubyte);
3221 break;
3222
3223 case GL_SHORT:
3224 coordTypeSize = sizeof(GLshort);
3225 break;
3226
3227 case GL_UNSIGNED_SHORT:
3228 coordTypeSize = sizeof(GLushort);
3229 break;
3230
3231 case GL_FLOAT:
3232 coordTypeSize = sizeof(GLfloat);
3233 break;
3234
3235 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003236 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003237 return false;
3238 }
3239
3240 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3241 checkedSize += (coordTypeSize * numCoords);
3242 if (!checkedSize.IsValid())
3243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003244 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245 return false;
3246 }
3247
3248 // early return skips command data validation when it doesn't exist.
3249 if (!commands)
3250 return true;
3251
3252 GLsizei expectedNumCoords = 0;
3253 for (GLsizei i = 0; i < numCommands; ++i)
3254 {
3255 switch (commands[i])
3256 {
3257 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3258 break;
3259 case GL_MOVE_TO_CHROMIUM:
3260 case GL_LINE_TO_CHROMIUM:
3261 expectedNumCoords += 2;
3262 break;
3263 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3264 expectedNumCoords += 4;
3265 break;
3266 case GL_CUBIC_CURVE_TO_CHROMIUM:
3267 expectedNumCoords += 6;
3268 break;
3269 case GL_CONIC_CURVE_TO_CHROMIUM:
3270 expectedNumCoords += 5;
3271 break;
3272 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003273 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003274 return false;
3275 }
3276 }
3277 if (expectedNumCoords != numCoords)
3278 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003279 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282
3283 return true;
3284}
3285
Jamie Madill007530e2017-12-28 14:27:04 -05003286bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003287{
3288 if (!context->getExtensions().pathRendering)
3289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003290 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 if (!context->hasPath(path))
3294 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298
3299 switch (pname)
3300 {
3301 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3302 if (value < 0.0f)
3303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003304 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003305 return false;
3306 }
3307 break;
3308 case GL_PATH_END_CAPS_CHROMIUM:
3309 switch (static_cast<GLenum>(value))
3310 {
3311 case GL_FLAT_CHROMIUM:
3312 case GL_SQUARE_CHROMIUM:
3313 case GL_ROUND_CHROMIUM:
3314 break;
3315 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 break;
3320 case GL_PATH_JOIN_STYLE_CHROMIUM:
3321 switch (static_cast<GLenum>(value))
3322 {
3323 case GL_MITER_REVERT_CHROMIUM:
3324 case GL_BEVEL_CHROMIUM:
3325 case GL_ROUND_CHROMIUM:
3326 break;
3327 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003328 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003329 return false;
3330 }
3331 case GL_PATH_MITER_LIMIT_CHROMIUM:
3332 if (value < 0.0f)
3333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003334 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003335 return false;
3336 }
3337 break;
3338
3339 case GL_PATH_STROKE_BOUND_CHROMIUM:
3340 // no errors, only clamping.
3341 break;
3342
3343 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003344 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 return false;
3346 }
3347 return true;
3348}
3349
Jamie Madill007530e2017-12-28 14:27:04 -05003350bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3351{
3352 // TODO(jmadill): Use proper clamping cast.
3353 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3354}
3355
3356bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003357{
3358 if (!context->getExtensions().pathRendering)
3359 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003360 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003361 return false;
3362 }
3363
3364 if (!context->hasPath(path))
3365 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003366 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003367 return false;
3368 }
3369 if (!value)
3370 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003371 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003372 return false;
3373 }
3374
3375 switch (pname)
3376 {
3377 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3378 case GL_PATH_END_CAPS_CHROMIUM:
3379 case GL_PATH_JOIN_STYLE_CHROMIUM:
3380 case GL_PATH_MITER_LIMIT_CHROMIUM:
3381 case GL_PATH_STROKE_BOUND_CHROMIUM:
3382 break;
3383
3384 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003385 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386 return false;
3387 }
3388
3389 return true;
3390}
3391
Jamie Madill007530e2017-12-28 14:27:04 -05003392bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3393{
3394 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3395 reinterpret_cast<GLfloat *>(value));
3396}
3397
3398bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003399{
3400 if (!context->getExtensions().pathRendering)
3401 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003402 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003403 return false;
3404 }
3405
3406 switch (func)
3407 {
3408 case GL_NEVER:
3409 case GL_ALWAYS:
3410 case GL_LESS:
3411 case GL_LEQUAL:
3412 case GL_EQUAL:
3413 case GL_GEQUAL:
3414 case GL_GREATER:
3415 case GL_NOTEQUAL:
3416 break;
3417 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003418 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003419 return false;
3420 }
3421
3422 return true;
3423}
3424
3425// Note that the spec specifies that for the path drawing commands
3426// if the path object is not an existing path object the command
3427// does nothing and no error is generated.
3428// However if the path object exists but has not been specified any
3429// commands then an error is generated.
3430
Jamie Madill007530e2017-12-28 14:27:04 -05003431bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003432{
3433 if (!context->getExtensions().pathRendering)
3434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003435 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003436 return false;
3437 }
3438 if (context->hasPath(path) && !context->hasPathData(path))
3439 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003440 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003441 return false;
3442 }
3443
3444 switch (fillMode)
3445 {
3446 case GL_COUNT_UP_CHROMIUM:
3447 case GL_COUNT_DOWN_CHROMIUM:
3448 break;
3449 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003450 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003451 return false;
3452 }
3453
3454 if (!isPow2(mask + 1))
3455 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003456 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003457 return false;
3458 }
3459
3460 return true;
3461}
3462
Jamie Madill007530e2017-12-28 14:27:04 -05003463bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003464{
3465 if (!context->getExtensions().pathRendering)
3466 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003467 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468 return false;
3469 }
3470 if (context->hasPath(path) && !context->hasPathData(path))
3471 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003472 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003473 return false;
3474 }
3475
3476 return true;
3477}
3478
Jamie Madill007530e2017-12-28 14:27:04 -05003479bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003480{
3481 if (!context->getExtensions().pathRendering)
3482 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003483 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003484 return false;
3485 }
3486 if (context->hasPath(path) && !context->hasPathData(path))
3487 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003488 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003489 return false;
3490 }
3491
3492 switch (coverMode)
3493 {
3494 case GL_CONVEX_HULL_CHROMIUM:
3495 case GL_BOUNDING_BOX_CHROMIUM:
3496 break;
3497 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003498 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003499 return false;
3500 }
3501 return true;
3502}
3503
Jamie Madill007530e2017-12-28 14:27:04 -05003504bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3505 GLuint path,
3506 GLenum fillMode,
3507 GLuint mask,
3508 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003509{
Jamie Madill007530e2017-12-28 14:27:04 -05003510 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3511 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512}
3513
Jamie Madill007530e2017-12-28 14:27:04 -05003514bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3515 GLuint path,
3516 GLint reference,
3517 GLuint mask,
3518 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519{
Jamie Madill007530e2017-12-28 14:27:04 -05003520 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3521 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003522}
3523
Jamie Madill007530e2017-12-28 14:27:04 -05003524bool ValidateIsPathCHROMIUM(Context *context)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525{
3526 if (!context->getExtensions().pathRendering)
3527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003528 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003529 return false;
3530 }
3531 return true;
3532}
3533
Jamie Madill007530e2017-12-28 14:27:04 -05003534bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3535 GLsizei numPaths,
3536 GLenum pathNameType,
3537 const void *paths,
3538 GLuint pathBase,
3539 GLenum coverMode,
3540 GLenum transformType,
3541 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003542{
3543 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3544 transformType, transformValues))
3545 return false;
3546
3547 switch (coverMode)
3548 {
3549 case GL_CONVEX_HULL_CHROMIUM:
3550 case GL_BOUNDING_BOX_CHROMIUM:
3551 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3552 break;
3553 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003554 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003555 return false;
3556 }
3557
3558 return true;
3559}
3560
Jamie Madill007530e2017-12-28 14:27:04 -05003561bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3562 GLsizei numPaths,
3563 GLenum pathNameType,
3564 const void *paths,
3565 GLuint pathBase,
3566 GLenum coverMode,
3567 GLenum transformType,
3568 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003569{
3570 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3571 transformType, transformValues))
3572 return false;
3573
3574 switch (coverMode)
3575 {
3576 case GL_CONVEX_HULL_CHROMIUM:
3577 case GL_BOUNDING_BOX_CHROMIUM:
3578 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3579 break;
3580 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003581 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003582 return false;
3583 }
3584
3585 return true;
3586}
3587
Jamie Madill007530e2017-12-28 14:27:04 -05003588bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3589 GLsizei numPaths,
3590 GLenum pathNameType,
3591 const void *paths,
3592 GLuint pathBase,
3593 GLenum fillMode,
3594 GLuint mask,
3595 GLenum transformType,
3596 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003597{
3598
3599 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3600 transformType, transformValues))
3601 return false;
3602
3603 switch (fillMode)
3604 {
3605 case GL_COUNT_UP_CHROMIUM:
3606 case GL_COUNT_DOWN_CHROMIUM:
3607 break;
3608 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003610 return false;
3611 }
3612 if (!isPow2(mask + 1))
3613 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003614 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003615 return false;
3616 }
3617 return true;
3618}
3619
Jamie Madill007530e2017-12-28 14:27:04 -05003620bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3621 GLsizei numPaths,
3622 GLenum pathNameType,
3623 const void *paths,
3624 GLuint pathBase,
3625 GLint reference,
3626 GLuint mask,
3627 GLenum transformType,
3628 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003629{
3630 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3631 transformType, transformValues))
3632 return false;
3633
3634 // no more validation here.
3635
3636 return true;
3637}
3638
Jamie Madill007530e2017-12-28 14:27:04 -05003639bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3640 GLsizei numPaths,
3641 GLenum pathNameType,
3642 const void *paths,
3643 GLuint pathBase,
3644 GLenum fillMode,
3645 GLuint mask,
3646 GLenum coverMode,
3647 GLenum transformType,
3648 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003649{
3650 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3651 transformType, transformValues))
3652 return false;
3653
3654 switch (coverMode)
3655 {
3656 case GL_CONVEX_HULL_CHROMIUM:
3657 case GL_BOUNDING_BOX_CHROMIUM:
3658 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3659 break;
3660 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003661 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003662 return false;
3663 }
3664
3665 switch (fillMode)
3666 {
3667 case GL_COUNT_UP_CHROMIUM:
3668 case GL_COUNT_DOWN_CHROMIUM:
3669 break;
3670 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003671 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003672 return false;
3673 }
3674 if (!isPow2(mask + 1))
3675 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003676 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003677 return false;
3678 }
3679
3680 return true;
3681}
3682
Jamie Madill007530e2017-12-28 14:27:04 -05003683bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3684 GLsizei numPaths,
3685 GLenum pathNameType,
3686 const void *paths,
3687 GLuint pathBase,
3688 GLint reference,
3689 GLuint mask,
3690 GLenum coverMode,
3691 GLenum transformType,
3692 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003693{
3694 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3695 transformType, transformValues))
3696 return false;
3697
3698 switch (coverMode)
3699 {
3700 case GL_CONVEX_HULL_CHROMIUM:
3701 case GL_BOUNDING_BOX_CHROMIUM:
3702 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3703 break;
3704 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003705 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003706 return false;
3707 }
3708
3709 return true;
3710}
3711
Jamie Madill007530e2017-12-28 14:27:04 -05003712bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3713 GLuint program,
3714 GLint location,
3715 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003716{
3717 if (!context->getExtensions().pathRendering)
3718 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003719 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003720 return false;
3721 }
3722
3723 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3724 if (location >= MaxLocation)
3725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003726 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003727 return false;
3728 }
3729
3730 const auto *programObject = context->getProgram(program);
3731 if (!programObject)
3732 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003733 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003734 return false;
3735 }
3736
3737 if (!name)
3738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003739 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003740 return false;
3741 }
3742
3743 if (angle::BeginsWith(name, "gl_"))
3744 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003745 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003746 return false;
3747 }
3748
3749 return true;
3750}
3751
Jamie Madill007530e2017-12-28 14:27:04 -05003752bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3753 GLuint program,
3754 GLint location,
3755 GLenum genMode,
3756 GLint components,
3757 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003758{
3759 if (!context->getExtensions().pathRendering)
3760 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003761 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003762 return false;
3763 }
3764
3765 const auto *programObject = context->getProgram(program);
3766 if (!programObject || programObject->isFlaggedForDeletion())
3767 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003768 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003769 return false;
3770 }
3771
3772 if (!programObject->isLinked())
3773 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003774 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003775 return false;
3776 }
3777
3778 switch (genMode)
3779 {
3780 case GL_NONE:
3781 if (components != 0)
3782 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003783 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003784 return false;
3785 }
3786 break;
3787
3788 case GL_OBJECT_LINEAR_CHROMIUM:
3789 case GL_EYE_LINEAR_CHROMIUM:
3790 case GL_CONSTANT_CHROMIUM:
3791 if (components < 1 || components > 4)
3792 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003793 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003794 return false;
3795 }
3796 if (!coeffs)
3797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003798 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003799 return false;
3800 }
3801 break;
3802
3803 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003804 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003805 return false;
3806 }
3807
3808 // If the location is -1 then the command is silently ignored
3809 // and no further validation is needed.
3810 if (location == -1)
3811 return true;
3812
Jamie Madillbd044ed2017-06-05 12:59:21 -04003813 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003814
3815 if (!binding.valid)
3816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003817 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003818 return false;
3819 }
3820
3821 if (binding.type != GL_NONE)
3822 {
3823 GLint expectedComponents = 0;
3824 switch (binding.type)
3825 {
3826 case GL_FLOAT:
3827 expectedComponents = 1;
3828 break;
3829 case GL_FLOAT_VEC2:
3830 expectedComponents = 2;
3831 break;
3832 case GL_FLOAT_VEC3:
3833 expectedComponents = 3;
3834 break;
3835 case GL_FLOAT_VEC4:
3836 expectedComponents = 4;
3837 break;
3838 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003839 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003840 InvalidOperation()
3841 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003842 return false;
3843 }
3844 if (expectedComponents != components && genMode != GL_NONE)
3845 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003846 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003847 return false;
3848 }
3849 }
3850 return true;
3851}
3852
Geoff Lang97073d12016-04-20 10:42:34 -07003853bool ValidateCopyTextureCHROMIUM(Context *context,
3854 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003855 GLint sourceLevel,
3856 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003857 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003858 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003859 GLint internalFormat,
3860 GLenum destType,
3861 GLboolean unpackFlipY,
3862 GLboolean unpackPremultiplyAlpha,
3863 GLboolean unpackUnmultiplyAlpha)
3864{
3865 if (!context->getExtensions().copyTexture)
3866 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003867 context->handleError(InvalidOperation()
3868 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003869 return false;
3870 }
3871
Geoff Lang4f0e0032017-05-01 16:04:35 -04003872 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003873 if (source == nullptr)
3874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003875 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003876 return false;
3877 }
3878
3879 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3880 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003881 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003882 return false;
3883 }
3884
3885 GLenum sourceTarget = source->getTarget();
3886 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003887
3888 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003890 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003891 return false;
3892 }
3893
Geoff Lang4f0e0032017-05-01 16:04:35 -04003894 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3895 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3896 if (sourceWidth == 0 || sourceHeight == 0)
3897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003898 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003899 return false;
3900 }
3901
3902 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3903 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003904 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003905 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003906 return false;
3907 }
3908
Geoff Lang63458a32017-10-30 15:16:53 -04003909 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3910 {
3911 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3912 return false;
3913 }
3914
Geoff Lang4f0e0032017-05-01 16:04:35 -04003915 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003916 if (dest == nullptr)
3917 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003918 context->handleError(InvalidValue()
3919 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003920 return false;
3921 }
3922
Geoff Lang4f0e0032017-05-01 16:04:35 -04003923 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003924 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003925 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003926 return false;
3927 }
3928
Geoff Lang4f0e0032017-05-01 16:04:35 -04003929 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3930 sourceHeight))
3931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003932 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 return false;
3934 }
3935
Geoff Lang97073d12016-04-20 10:42:34 -07003936 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3937 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003938 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003939 return false;
3940 }
3941
Geoff Lang4f0e0032017-05-01 16:04:35 -04003942 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3943 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003944 context->handleError(
3945 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003946 return false;
3947 }
3948
Geoff Lang97073d12016-04-20 10:42:34 -07003949 if (dest->getImmutableFormat())
3950 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003951 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003952 return false;
3953 }
3954
3955 return true;
3956}
3957
3958bool ValidateCopySubTextureCHROMIUM(Context *context,
3959 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003960 GLint sourceLevel,
3961 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003962 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003963 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003964 GLint xoffset,
3965 GLint yoffset,
3966 GLint x,
3967 GLint y,
3968 GLsizei width,
3969 GLsizei height,
3970 GLboolean unpackFlipY,
3971 GLboolean unpackPremultiplyAlpha,
3972 GLboolean unpackUnmultiplyAlpha)
3973{
3974 if (!context->getExtensions().copyTexture)
3975 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003976 context->handleError(InvalidOperation()
3977 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003978 return false;
3979 }
3980
Geoff Lang4f0e0032017-05-01 16:04:35 -04003981 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003982 if (source == nullptr)
3983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003984 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003985 return false;
3986 }
3987
3988 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3989 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003990 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003991 return false;
3992 }
3993
3994 GLenum sourceTarget = source->getTarget();
3995 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003996
3997 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3998 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003999 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004000 return false;
4001 }
4002
4003 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4004 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004006 context->handleError(InvalidValue()
4007 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004008 return false;
4009 }
4010
4011 if (x < 0 || y < 0)
4012 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004013 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004014 return false;
4015 }
4016
4017 if (width < 0 || height < 0)
4018 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004019 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004020 return false;
4021 }
4022
Geoff Lang4f0e0032017-05-01 16:04:35 -04004023 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4024 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004025 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004026 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004027 return false;
4028 }
4029
Geoff Lang4f0e0032017-05-01 16:04:35 -04004030 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4031 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004032 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004033 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004034 return false;
4035 }
4036
Geoff Lang63458a32017-10-30 15:16:53 -04004037 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4038 {
4039 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4040 return false;
4041 }
4042
Geoff Lang4f0e0032017-05-01 16:04:35 -04004043 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004044 if (dest == nullptr)
4045 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004046 context->handleError(InvalidValue()
4047 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004048 return false;
4049 }
4050
Geoff Lang4f0e0032017-05-01 16:04:35 -04004051 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004052 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004053 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004054 return false;
4055 }
4056
Geoff Lang4f0e0032017-05-01 16:04:35 -04004057 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07004058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004059 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004060 return false;
4061 }
4062
Geoff Lang4f0e0032017-05-01 16:04:35 -04004063 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4064 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004065 context
4066 ->handleError(InvalidOperation()
4067 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004068 return false;
4069 }
4070
4071 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4072 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004073 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004074 context->handleError(InvalidOperation()
4075 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004076 return false;
4077 }
4078
4079 if (xoffset < 0 || yoffset < 0)
4080 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004081 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004082 return false;
4083 }
4084
Geoff Lang4f0e0032017-05-01 16:04:35 -04004085 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4086 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004087 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004088 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004089 return false;
4090 }
4091
4092 return true;
4093}
4094
Geoff Lang47110bf2016-04-20 11:13:22 -07004095bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4096{
4097 if (!context->getExtensions().copyCompressedTexture)
4098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004099 context->handleError(InvalidOperation()
4100 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004101 return false;
4102 }
4103
4104 const gl::Texture *source = context->getTexture(sourceId);
4105 if (source == nullptr)
4106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004107 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004108 return false;
4109 }
4110
4111 if (source->getTarget() != GL_TEXTURE_2D)
4112 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004113 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004114 return false;
4115 }
4116
4117 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004119 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004120 return false;
4121 }
4122
4123 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4124 if (!sourceFormat.info->compressed)
4125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004126 context->handleError(InvalidOperation()
4127 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004128 return false;
4129 }
4130
4131 const gl::Texture *dest = context->getTexture(destId);
4132 if (dest == nullptr)
4133 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004134 context->handleError(InvalidValue()
4135 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004136 return false;
4137 }
4138
4139 if (dest->getTarget() != GL_TEXTURE_2D)
4140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004141 context->handleError(InvalidValue()
4142 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004143 return false;
4144 }
4145
4146 if (dest->getImmutableFormat())
4147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004148 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004149 return false;
4150 }
4151
4152 return true;
4153}
4154
Martin Radev4c4c8e72016-08-04 12:25:34 +03004155bool ValidateCreateShader(Context *context, GLenum type)
4156{
4157 switch (type)
4158 {
4159 case GL_VERTEX_SHADER:
4160 case GL_FRAGMENT_SHADER:
4161 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004162
Martin Radev4c4c8e72016-08-04 12:25:34 +03004163 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004164 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004165 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004166 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004167 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004168 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004169 break;
4170
Jiawei Shao89be29a2017-11-06 14:36:45 +08004171 case GL_GEOMETRY_SHADER_EXT:
4172 if (!context->getExtensions().geometryShader)
4173 {
4174 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4175 return false;
4176 }
4177 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004178 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004179 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004180 return false;
4181 }
Jamie Madill29639852016-09-02 15:00:09 -04004182
4183 return true;
4184}
4185
4186bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004187 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004188 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004189 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004190 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004191{
4192 if (size < 0)
4193 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004194 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004195 return false;
4196 }
4197
4198 switch (usage)
4199 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004200 case BufferUsage::StreamDraw:
4201 case BufferUsage::StaticDraw:
4202 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004203 break;
4204
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004205 case BufferUsage::StreamRead:
4206 case BufferUsage::StaticRead:
4207 case BufferUsage::DynamicRead:
4208 case BufferUsage::StreamCopy:
4209 case BufferUsage::StaticCopy:
4210 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004211 if (context->getClientMajorVersion() < 3)
4212 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004213 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004214 return false;
4215 }
4216 break;
4217
4218 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004219 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004220 return false;
4221 }
4222
Corentin Walleze4477002017-12-01 14:39:58 -05004223 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004224 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004226 return false;
4227 }
4228
4229 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4230
4231 if (!buffer)
4232 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004233 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004234 return false;
4235 }
4236
4237 return true;
4238}
4239
4240bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004241 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004242 GLintptr offset,
4243 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004244 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004245{
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004247 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004248 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4249 return false;
4250 }
4251
4252 if (offset < 0)
4253 {
4254 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004255 return false;
4256 }
4257
Corentin Walleze4477002017-12-01 14:39:58 -05004258 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004261 return false;
4262 }
4263
4264 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4265
4266 if (!buffer)
4267 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004268 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004269 return false;
4270 }
4271
4272 if (buffer->isMapped())
4273 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004274 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004275 return false;
4276 }
4277
4278 // Check for possible overflow of size + offset
4279 angle::CheckedNumeric<size_t> checkedSize(size);
4280 checkedSize += offset;
4281 if (!checkedSize.IsValid())
4282 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004283 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004284 return false;
4285 }
4286
4287 if (size + offset > buffer->getSize())
4288 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004289 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004290 return false;
4291 }
4292
Martin Radev4c4c8e72016-08-04 12:25:34 +03004293 return true;
4294}
4295
Geoff Lang111a99e2017-10-17 10:58:41 -04004296bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004297{
Geoff Langc339c4e2016-11-29 10:37:36 -05004298 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004299 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004300 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004301 return false;
4302 }
4303
Geoff Lang111a99e2017-10-17 10:58:41 -04004304 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004306 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004307 return false;
4308 }
4309
4310 return true;
4311}
4312
Jamie Madillef300b12016-10-07 15:12:09 -04004313bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4314{
4315 if (texture < GL_TEXTURE0 ||
4316 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004318 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004319 return false;
4320 }
4321
4322 return true;
4323}
4324
4325bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4326{
4327 Program *programObject = GetValidProgram(context, program);
4328 if (!programObject)
4329 {
4330 return false;
4331 }
4332
4333 Shader *shaderObject = GetValidShader(context, shader);
4334 if (!shaderObject)
4335 {
4336 return false;
4337 }
4338
4339 switch (shaderObject->getType())
4340 {
4341 case GL_VERTEX_SHADER:
4342 {
4343 if (programObject->getAttachedVertexShader())
4344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004346 return false;
4347 }
4348 break;
4349 }
4350 case GL_FRAGMENT_SHADER:
4351 {
4352 if (programObject->getAttachedFragmentShader())
4353 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004355 return false;
4356 }
4357 break;
4358 }
4359 case GL_COMPUTE_SHADER:
4360 {
4361 if (programObject->getAttachedComputeShader())
4362 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004364 return false;
4365 }
4366 break;
4367 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004368 case GL_GEOMETRY_SHADER_EXT:
4369 {
4370 if (programObject->getAttachedGeometryShader())
4371 {
4372 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4373 return false;
4374 }
4375 break;
4376 }
Jamie Madillef300b12016-10-07 15:12:09 -04004377 default:
4378 UNREACHABLE();
4379 break;
4380 }
4381
4382 return true;
4383}
4384
Jamie Madill01a80ee2016-11-07 12:06:18 -05004385bool ValidateBindAttribLocation(ValidationContext *context,
4386 GLuint program,
4387 GLuint index,
4388 const GLchar *name)
4389{
4390 if (index >= MAX_VERTEX_ATTRIBS)
4391 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004392 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004393 return false;
4394 }
4395
4396 if (strncmp(name, "gl_", 3) == 0)
4397 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004399 return false;
4400 }
4401
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004402 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004403 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004404 const size_t length = strlen(name);
4405
4406 if (!IsValidESSLString(name, length))
4407 {
4408 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4409 // for shader-related entry points
4410 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4411 return false;
4412 }
4413
4414 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4415 {
4416 return false;
4417 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004418 }
4419
Jamie Madill01a80ee2016-11-07 12:06:18 -05004420 return GetValidProgram(context, program) != nullptr;
4421}
4422
Corentin Wallez336129f2017-10-17 15:55:40 -04004423bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004424{
Corentin Walleze4477002017-12-01 14:39:58 -05004425 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004427 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004428 return false;
4429 }
4430
4431 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4432 !context->isBufferGenerated(buffer))
4433 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004434 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004435 return false;
4436 }
4437
4438 return true;
4439}
4440
4441bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4442{
Geoff Lange8afa902017-09-27 15:00:43 -04004443 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004445 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004446 return false;
4447 }
4448
4449 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4450 !context->isFramebufferGenerated(framebuffer))
4451 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004452 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004453 return false;
4454 }
4455
4456 return true;
4457}
4458
4459bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4460{
4461 if (target != GL_RENDERBUFFER)
4462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004463 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004464 return false;
4465 }
4466
4467 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4468 !context->isRenderbufferGenerated(renderbuffer))
4469 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004470 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004471 return false;
4472 }
4473
4474 return true;
4475}
4476
Geoff Lang50cac572017-09-26 17:37:43 -04004477static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004478{
4479 switch (mode)
4480 {
4481 case GL_FUNC_ADD:
4482 case GL_FUNC_SUBTRACT:
4483 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004484 return true;
4485
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004486 case GL_MIN:
4487 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004488 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004489
4490 default:
4491 return false;
4492 }
4493}
4494
Jamie Madillc1d770e2017-04-13 17:31:24 -04004495bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004496 GLfloat red,
4497 GLfloat green,
4498 GLfloat blue,
4499 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004500{
4501 return true;
4502}
4503
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004504bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4505{
Geoff Lang50cac572017-09-26 17:37:43 -04004506 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004508 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509 return false;
4510 }
4511
4512 return true;
4513}
4514
4515bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4516{
Geoff Lang50cac572017-09-26 17:37:43 -04004517 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004519 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004520 return false;
4521 }
4522
Geoff Lang50cac572017-09-26 17:37:43 -04004523 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004524 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004525 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004526 return false;
4527 }
4528
4529 return true;
4530}
4531
4532bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4533{
4534 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4535}
4536
4537static bool ValidSrcBlendFunc(GLenum srcBlend)
4538{
4539 switch (srcBlend)
4540 {
4541 case GL_ZERO:
4542 case GL_ONE:
4543 case GL_SRC_COLOR:
4544 case GL_ONE_MINUS_SRC_COLOR:
4545 case GL_DST_COLOR:
4546 case GL_ONE_MINUS_DST_COLOR:
4547 case GL_SRC_ALPHA:
4548 case GL_ONE_MINUS_SRC_ALPHA:
4549 case GL_DST_ALPHA:
4550 case GL_ONE_MINUS_DST_ALPHA:
4551 case GL_CONSTANT_COLOR:
4552 case GL_ONE_MINUS_CONSTANT_COLOR:
4553 case GL_CONSTANT_ALPHA:
4554 case GL_ONE_MINUS_CONSTANT_ALPHA:
4555 case GL_SRC_ALPHA_SATURATE:
4556 return true;
4557
4558 default:
4559 return false;
4560 }
4561}
4562
4563static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4564{
4565 switch (dstBlend)
4566 {
4567 case GL_ZERO:
4568 case GL_ONE:
4569 case GL_SRC_COLOR:
4570 case GL_ONE_MINUS_SRC_COLOR:
4571 case GL_DST_COLOR:
4572 case GL_ONE_MINUS_DST_COLOR:
4573 case GL_SRC_ALPHA:
4574 case GL_ONE_MINUS_SRC_ALPHA:
4575 case GL_DST_ALPHA:
4576 case GL_ONE_MINUS_DST_ALPHA:
4577 case GL_CONSTANT_COLOR:
4578 case GL_ONE_MINUS_CONSTANT_COLOR:
4579 case GL_CONSTANT_ALPHA:
4580 case GL_ONE_MINUS_CONSTANT_ALPHA:
4581 return true;
4582
4583 case GL_SRC_ALPHA_SATURATE:
4584 return (contextMajorVersion >= 3);
4585
4586 default:
4587 return false;
4588 }
4589}
4590
4591bool ValidateBlendFuncSeparate(ValidationContext *context,
4592 GLenum srcRGB,
4593 GLenum dstRGB,
4594 GLenum srcAlpha,
4595 GLenum dstAlpha)
4596{
4597 if (!ValidSrcBlendFunc(srcRGB))
4598 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004599 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004600 return false;
4601 }
4602
4603 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4604 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004605 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004606 return false;
4607 }
4608
4609 if (!ValidSrcBlendFunc(srcAlpha))
4610 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 return false;
4613 }
4614
4615 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004618 return false;
4619 }
4620
Frank Henigman146e8a12017-03-02 23:22:37 -05004621 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4622 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004623 {
4624 bool constantColorUsed =
4625 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4626 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4627
4628 bool constantAlphaUsed =
4629 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4630 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4631
4632 if (constantColorUsed && constantAlphaUsed)
4633 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004634 const char *msg;
4635 if (context->getExtensions().webglCompatibility)
4636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004637 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004638 }
4639 else
4640 {
4641 msg =
4642 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4643 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4644 "implementation.";
4645 ERR() << msg;
4646 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004647 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004648 return false;
4649 }
4650 }
4651
4652 return true;
4653}
4654
Geoff Langc339c4e2016-11-29 10:37:36 -05004655bool ValidateGetString(Context *context, GLenum name)
4656{
4657 switch (name)
4658 {
4659 case GL_VENDOR:
4660 case GL_RENDERER:
4661 case GL_VERSION:
4662 case GL_SHADING_LANGUAGE_VERSION:
4663 case GL_EXTENSIONS:
4664 break;
4665
4666 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4667 if (!context->getExtensions().requestExtension)
4668 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004669 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004670 return false;
4671 }
4672 break;
4673
4674 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004675 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004676 return false;
4677 }
4678
4679 return true;
4680}
4681
Geoff Lang47c48082016-12-07 15:38:13 -05004682bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4683{
4684 if (width <= 0.0f || isNaN(width))
4685 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004686 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004687 return false;
4688 }
4689
4690 return true;
4691}
4692
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693bool ValidateVertexAttribPointer(ValidationContext *context,
4694 GLuint index,
4695 GLint size,
4696 GLenum type,
4697 GLboolean normalized,
4698 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004699 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700{
Shao80957d92017-02-20 21:25:59 +08004701 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004702 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004703 return false;
4704 }
4705
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706 if (stride < 0)
4707 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004708 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004709 return false;
4710 }
4711
Shao80957d92017-02-20 21:25:59 +08004712 const Caps &caps = context->getCaps();
4713 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004714 {
Shao80957d92017-02-20 21:25:59 +08004715 if (stride > caps.maxVertexAttribStride)
4716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004717 context->handleError(InvalidValue()
4718 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004719 return false;
4720 }
4721
4722 if (index >= caps.maxVertexAttribBindings)
4723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004724 context->handleError(InvalidValue()
4725 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004726 return false;
4727 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 }
4729
4730 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4731 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4732 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4733 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004734 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4735 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004736 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4737 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004739 context
4740 ->handleError(InvalidOperation()
4741 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004742 return false;
4743 }
4744
4745 if (context->getExtensions().webglCompatibility)
4746 {
4747 // WebGL 1.0 [Section 6.14] Fixed point support
4748 // The WebGL API does not support the GL_FIXED data type.
4749 if (type == GL_FIXED)
4750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004751 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004752 return false;
4753 }
4754
Geoff Lang2d62ab72017-03-23 16:54:40 -04004755 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004756 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004757 return false;
4758 }
4759 }
4760
4761 return true;
4762}
4763
Jamie Madill876429b2017-04-20 15:46:24 -04004764bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004765{
4766 if (context->getExtensions().webglCompatibility && zNear > zFar)
4767 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004768 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004769 return false;
4770 }
4771
4772 return true;
4773}
4774
Jamie Madille8fb6402017-02-14 17:56:40 -05004775bool ValidateRenderbufferStorage(ValidationContext *context,
4776 GLenum target,
4777 GLenum internalformat,
4778 GLsizei width,
4779 GLsizei height)
4780{
4781 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4782 height);
4783}
4784
4785bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4786 GLenum target,
4787 GLsizei samples,
4788 GLenum internalformat,
4789 GLsizei width,
4790 GLsizei height)
4791{
4792 if (!context->getExtensions().framebufferMultisample)
4793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004794 context->handleError(InvalidOperation()
4795 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004796 return false;
4797 }
4798
4799 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4800 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4801 // generated.
4802 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004804 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004805 return false;
4806 }
4807
4808 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4809 // the specified storage. This is different than ES 3.0 in which a sample number higher
4810 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4811 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4812 if (context->getClientMajorVersion() >= 3)
4813 {
4814 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4815 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004817 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004818 return false;
4819 }
4820 }
4821
4822 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4823 width, height);
4824}
4825
Jamie Madillc1d770e2017-04-13 17:31:24 -04004826bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4827{
Geoff Lange8afa902017-09-27 15:00:43 -04004828 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004830 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004831 return false;
4832 }
4833
4834 return true;
4835}
4836
4837bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004838 GLfloat red,
4839 GLfloat green,
4840 GLfloat blue,
4841 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004842{
4843 return true;
4844}
4845
Jamie Madill876429b2017-04-20 15:46:24 -04004846bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847{
4848 return true;
4849}
4850
4851bool ValidateClearStencil(ValidationContext *context, GLint s)
4852{
4853 return true;
4854}
4855
4856bool ValidateColorMask(ValidationContext *context,
4857 GLboolean red,
4858 GLboolean green,
4859 GLboolean blue,
4860 GLboolean alpha)
4861{
4862 return true;
4863}
4864
4865bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4866{
4867 return true;
4868}
4869
4870bool ValidateCreateProgram(ValidationContext *context)
4871{
4872 return true;
4873}
4874
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004875bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876{
4877 switch (mode)
4878 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004879 case CullFaceMode::Front:
4880 case CullFaceMode::Back:
4881 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004882 break;
4883
4884 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004885 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004886 return false;
4887 }
4888
4889 return true;
4890}
4891
4892bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4893{
4894 if (program == 0)
4895 {
4896 return false;
4897 }
4898
4899 if (!context->getProgram(program))
4900 {
4901 if (context->getShader(program))
4902 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004903 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004904 return false;
4905 }
4906 else
4907 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004908 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004909 return false;
4910 }
4911 }
4912
4913 return true;
4914}
4915
4916bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4917{
4918 if (shader == 0)
4919 {
4920 return false;
4921 }
4922
4923 if (!context->getShader(shader))
4924 {
4925 if (context->getProgram(shader))
4926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004927 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004928 return false;
4929 }
4930 else
4931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004932 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004933 return false;
4934 }
4935 }
4936
4937 return true;
4938}
4939
4940bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4941{
4942 switch (func)
4943 {
4944 case GL_NEVER:
4945 case GL_ALWAYS:
4946 case GL_LESS:
4947 case GL_LEQUAL:
4948 case GL_EQUAL:
4949 case GL_GREATER:
4950 case GL_GEQUAL:
4951 case GL_NOTEQUAL:
4952 break;
4953
4954 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004955 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004956 return false;
4957 }
4958
4959 return true;
4960}
4961
4962bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4963{
4964 return true;
4965}
4966
4967bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4968{
4969 Program *programObject = GetValidProgram(context, program);
4970 if (!programObject)
4971 {
4972 return false;
4973 }
4974
4975 Shader *shaderObject = GetValidShader(context, shader);
4976 if (!shaderObject)
4977 {
4978 return false;
4979 }
4980
4981 const Shader *attachedShader = nullptr;
4982
4983 switch (shaderObject->getType())
4984 {
4985 case GL_VERTEX_SHADER:
4986 {
4987 attachedShader = programObject->getAttachedVertexShader();
4988 break;
4989 }
4990 case GL_FRAGMENT_SHADER:
4991 {
4992 attachedShader = programObject->getAttachedFragmentShader();
4993 break;
4994 }
4995 case GL_COMPUTE_SHADER:
4996 {
4997 attachedShader = programObject->getAttachedComputeShader();
4998 break;
4999 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08005000 case GL_GEOMETRY_SHADER_EXT:
5001 {
5002 attachedShader = programObject->getAttachedGeometryShader();
5003 break;
5004 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04005005 default:
5006 UNREACHABLE();
5007 return false;
5008 }
5009
5010 if (attachedShader != shaderObject)
5011 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005012 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005013 return false;
5014 }
5015
5016 return true;
5017}
5018
5019bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5020{
5021 if (index >= MAX_VERTEX_ATTRIBS)
5022 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005023 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005024 return false;
5025 }
5026
5027 return true;
5028}
5029
5030bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5031{
5032 if (index >= MAX_VERTEX_ATTRIBS)
5033 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005034 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005035 return false;
5036 }
5037
5038 return true;
5039}
5040
5041bool ValidateFinish(ValidationContext *context)
5042{
5043 return true;
5044}
5045
5046bool ValidateFlush(ValidationContext *context)
5047{
5048 return true;
5049}
5050
5051bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5052{
5053 switch (mode)
5054 {
5055 case GL_CW:
5056 case GL_CCW:
5057 break;
5058 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005059 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005060 return false;
5061 }
5062
5063 return true;
5064}
5065
5066bool ValidateGetActiveAttrib(ValidationContext *context,
5067 GLuint program,
5068 GLuint index,
5069 GLsizei bufsize,
5070 GLsizei *length,
5071 GLint *size,
5072 GLenum *type,
5073 GLchar *name)
5074{
5075 if (bufsize < 0)
5076 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005077 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005078 return false;
5079 }
5080
5081 Program *programObject = GetValidProgram(context, program);
5082
5083 if (!programObject)
5084 {
5085 return false;
5086 }
5087
5088 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5089 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005090 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005091 return false;
5092 }
5093
5094 return true;
5095}
5096
5097bool ValidateGetActiveUniform(ValidationContext *context,
5098 GLuint program,
5099 GLuint index,
5100 GLsizei bufsize,
5101 GLsizei *length,
5102 GLint *size,
5103 GLenum *type,
5104 GLchar *name)
5105{
5106 if (bufsize < 0)
5107 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005108 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005109 return false;
5110 }
5111
5112 Program *programObject = GetValidProgram(context, program);
5113
5114 if (!programObject)
5115 {
5116 return false;
5117 }
5118
5119 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5120 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005121 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005122 return false;
5123 }
5124
5125 return true;
5126}
5127
5128bool ValidateGetAttachedShaders(ValidationContext *context,
5129 GLuint program,
5130 GLsizei maxcount,
5131 GLsizei *count,
5132 GLuint *shaders)
5133{
5134 if (maxcount < 0)
5135 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005136 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137 return false;
5138 }
5139
5140 Program *programObject = GetValidProgram(context, program);
5141
5142 if (!programObject)
5143 {
5144 return false;
5145 }
5146
5147 return true;
5148}
5149
5150bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5151{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005152 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5153 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005154 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005156 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005157 return false;
5158 }
5159
Jamie Madillc1d770e2017-04-13 17:31:24 -04005160 Program *programObject = GetValidProgram(context, program);
5161
5162 if (!programObject)
5163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005165 return false;
5166 }
5167
5168 if (!programObject->isLinked())
5169 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005170 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171 return false;
5172 }
5173
5174 return true;
5175}
5176
5177bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5178{
5179 GLenum nativeType;
5180 unsigned int numParams = 0;
5181 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5182}
5183
5184bool ValidateGetError(ValidationContext *context)
5185{
5186 return true;
5187}
5188
5189bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5190{
5191 GLenum nativeType;
5192 unsigned int numParams = 0;
5193 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5194}
5195
5196bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5197{
5198 GLenum nativeType;
5199 unsigned int numParams = 0;
5200 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5201}
5202
5203bool ValidateGetProgramInfoLog(ValidationContext *context,
5204 GLuint program,
5205 GLsizei bufsize,
5206 GLsizei *length,
5207 GLchar *infolog)
5208{
5209 if (bufsize < 0)
5210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005211 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005212 return false;
5213 }
5214
5215 Program *programObject = GetValidProgram(context, program);
5216 if (!programObject)
5217 {
5218 return false;
5219 }
5220
5221 return true;
5222}
5223
5224bool ValidateGetShaderInfoLog(ValidationContext *context,
5225 GLuint shader,
5226 GLsizei bufsize,
5227 GLsizei *length,
5228 GLchar *infolog)
5229{
5230 if (bufsize < 0)
5231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005232 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005233 return false;
5234 }
5235
5236 Shader *shaderObject = GetValidShader(context, shader);
5237 if (!shaderObject)
5238 {
5239 return false;
5240 }
5241
5242 return true;
5243}
5244
5245bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5246 GLenum shadertype,
5247 GLenum precisiontype,
5248 GLint *range,
5249 GLint *precision)
5250{
5251 switch (shadertype)
5252 {
5253 case GL_VERTEX_SHADER:
5254 case GL_FRAGMENT_SHADER:
5255 break;
5256 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005257 context->handleError(InvalidOperation()
5258 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005259 return false;
5260 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005261 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005262 return false;
5263 }
5264
5265 switch (precisiontype)
5266 {
5267 case GL_LOW_FLOAT:
5268 case GL_MEDIUM_FLOAT:
5269 case GL_HIGH_FLOAT:
5270 case GL_LOW_INT:
5271 case GL_MEDIUM_INT:
5272 case GL_HIGH_INT:
5273 break;
5274
5275 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005276 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005277 return false;
5278 }
5279
5280 return true;
5281}
5282
5283bool ValidateGetShaderSource(ValidationContext *context,
5284 GLuint shader,
5285 GLsizei bufsize,
5286 GLsizei *length,
5287 GLchar *source)
5288{
5289 if (bufsize < 0)
5290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005291 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005292 return false;
5293 }
5294
5295 Shader *shaderObject = GetValidShader(context, shader);
5296 if (!shaderObject)
5297 {
5298 return false;
5299 }
5300
5301 return true;
5302}
5303
5304bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5305{
5306 if (strstr(name, "gl_") == name)
5307 {
5308 return false;
5309 }
5310
Geoff Langfc32e8b2017-05-31 14:16:59 -04005311 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5312 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005313 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005314 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005315 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005316 return false;
5317 }
5318
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 Program *programObject = GetValidProgram(context, program);
5320
5321 if (!programObject)
5322 {
5323 return false;
5324 }
5325
5326 if (!programObject->isLinked())
5327 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005328 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005329 return false;
5330 }
5331
5332 return true;
5333}
5334
5335bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5336{
5337 switch (mode)
5338 {
5339 case GL_FASTEST:
5340 case GL_NICEST:
5341 case GL_DONT_CARE:
5342 break;
5343
5344 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005345 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346 return false;
5347 }
5348
5349 switch (target)
5350 {
5351 case GL_GENERATE_MIPMAP_HINT:
5352 break;
5353
Geoff Lange7bd2182017-06-16 16:13:13 -04005354 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5355 if (context->getClientVersion() < ES_3_0 &&
5356 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005357 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005358 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005359 return false;
5360 }
5361 break;
5362
5363 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005364 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005365 return false;
5366 }
5367
5368 return true;
5369}
5370
5371bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5372{
5373 return true;
5374}
5375
5376bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5377{
5378 return true;
5379}
5380
5381bool ValidateIsProgram(ValidationContext *context, GLuint program)
5382{
5383 return true;
5384}
5385
5386bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5387{
5388 return true;
5389}
5390
5391bool ValidateIsShader(ValidationContext *context, GLuint shader)
5392{
5393 return true;
5394}
5395
5396bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5397{
5398 return true;
5399}
5400
5401bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5402{
5403 if (context->getClientMajorVersion() < 3)
5404 {
5405 switch (pname)
5406 {
5407 case GL_UNPACK_IMAGE_HEIGHT:
5408 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005409 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410 return false;
5411
5412 case GL_UNPACK_ROW_LENGTH:
5413 case GL_UNPACK_SKIP_ROWS:
5414 case GL_UNPACK_SKIP_PIXELS:
5415 if (!context->getExtensions().unpackSubimage)
5416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005417 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418 return false;
5419 }
5420 break;
5421
5422 case GL_PACK_ROW_LENGTH:
5423 case GL_PACK_SKIP_ROWS:
5424 case GL_PACK_SKIP_PIXELS:
5425 if (!context->getExtensions().packSubimage)
5426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005427 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 return false;
5429 }
5430 break;
5431 }
5432 }
5433
5434 if (param < 0)
5435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005436 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439
5440 switch (pname)
5441 {
5442 case GL_UNPACK_ALIGNMENT:
5443 if (param != 1 && param != 2 && param != 4 && param != 8)
5444 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005445 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005446 return false;
5447 }
5448 break;
5449
5450 case GL_PACK_ALIGNMENT:
5451 if (param != 1 && param != 2 && param != 4 && param != 8)
5452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005453 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005454 return false;
5455 }
5456 break;
5457
5458 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005459 if (!context->getExtensions().packReverseRowOrder)
5460 {
5461 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5462 }
5463 break;
5464
Jamie Madillc1d770e2017-04-13 17:31:24 -04005465 case GL_UNPACK_ROW_LENGTH:
5466 case GL_UNPACK_IMAGE_HEIGHT:
5467 case GL_UNPACK_SKIP_IMAGES:
5468 case GL_UNPACK_SKIP_ROWS:
5469 case GL_UNPACK_SKIP_PIXELS:
5470 case GL_PACK_ROW_LENGTH:
5471 case GL_PACK_SKIP_ROWS:
5472 case GL_PACK_SKIP_PIXELS:
5473 break;
5474
5475 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005476 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 return false;
5478 }
5479
5480 return true;
5481}
5482
5483bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5484{
5485 return true;
5486}
5487
5488bool ValidateReleaseShaderCompiler(ValidationContext *context)
5489{
5490 return true;
5491}
5492
Jamie Madill876429b2017-04-20 15:46:24 -04005493bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494{
5495 return true;
5496}
5497
5498bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5499{
5500 if (width < 0 || height < 0)
5501 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005502 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005503 return false;
5504 }
5505
5506 return true;
5507}
5508
5509bool ValidateShaderBinary(ValidationContext *context,
5510 GLsizei n,
5511 const GLuint *shaders,
5512 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005513 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005514 GLsizei length)
5515{
5516 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5517 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5518 shaderBinaryFormats.end())
5519 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005520 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 return false;
5522 }
5523
5524 return true;
5525}
5526
5527bool ValidateShaderSource(ValidationContext *context,
5528 GLuint shader,
5529 GLsizei count,
5530 const GLchar *const *string,
5531 const GLint *length)
5532{
5533 if (count < 0)
5534 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005535 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005536 return false;
5537 }
5538
Geoff Langfc32e8b2017-05-31 14:16:59 -04005539 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5540 // shader-related entry points
5541 if (context->getExtensions().webglCompatibility)
5542 {
5543 for (GLsizei i = 0; i < count; i++)
5544 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005545 size_t len =
5546 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005547
5548 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005549 if (!IsValidESSLShaderSourceString(string[i], len,
5550 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005551 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005552 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005553 return false;
5554 }
5555 }
5556 }
5557
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 Shader *shaderObject = GetValidShader(context, shader);
5559 if (!shaderObject)
5560 {
5561 return false;
5562 }
5563
5564 return true;
5565}
5566
5567bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5568{
5569 if (!IsValidStencilFunc(func))
5570 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572 return false;
5573 }
5574
5575 return true;
5576}
5577
5578bool ValidateStencilFuncSeparate(ValidationContext *context,
5579 GLenum face,
5580 GLenum func,
5581 GLint ref,
5582 GLuint mask)
5583{
5584 if (!IsValidStencilFace(face))
5585 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005586 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587 return false;
5588 }
5589
5590 if (!IsValidStencilFunc(func))
5591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005593 return false;
5594 }
5595
5596 return true;
5597}
5598
5599bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5600{
5601 return true;
5602}
5603
5604bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5605{
5606 if (!IsValidStencilFace(face))
5607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609 return false;
5610 }
5611
5612 return true;
5613}
5614
5615bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5616{
5617 if (!IsValidStencilOp(fail))
5618 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005619 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620 return false;
5621 }
5622
5623 if (!IsValidStencilOp(zfail))
5624 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005625 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005626 return false;
5627 }
5628
5629 if (!IsValidStencilOp(zpass))
5630 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005631 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005632 return false;
5633 }
5634
5635 return true;
5636}
5637
5638bool ValidateStencilOpSeparate(ValidationContext *context,
5639 GLenum face,
5640 GLenum fail,
5641 GLenum zfail,
5642 GLenum zpass)
5643{
5644 if (!IsValidStencilFace(face))
5645 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005646 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005647 return false;
5648 }
5649
5650 return ValidateStencilOp(context, fail, zfail, zpass);
5651}
5652
5653bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5654{
5655 return ValidateUniform(context, GL_FLOAT, location, 1);
5656}
5657
5658bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5659{
5660 return ValidateUniform(context, GL_FLOAT, location, count);
5661}
5662
Jamie Madillbe849e42017-05-02 15:49:00 -04005663bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5664{
5665 return ValidateUniform1iv(context, location, 1, &x);
5666}
5667
Jamie Madillc1d770e2017-04-13 17:31:24 -04005668bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5669{
5670 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5671}
5672
5673bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5674{
5675 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5676}
5677
5678bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5679{
5680 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5681}
5682
5683bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5684{
5685 return ValidateUniform(context, GL_INT_VEC2, location, count);
5686}
5687
5688bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5689{
5690 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5691}
5692
5693bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5694{
5695 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5696}
5697
5698bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5699{
5700 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5701}
5702
5703bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5704{
5705 return ValidateUniform(context, GL_INT_VEC3, location, count);
5706}
5707
5708bool ValidateUniform4f(ValidationContext *context,
5709 GLint location,
5710 GLfloat x,
5711 GLfloat y,
5712 GLfloat z,
5713 GLfloat w)
5714{
5715 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5716}
5717
5718bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5719{
5720 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5721}
5722
5723bool ValidateUniform4i(ValidationContext *context,
5724 GLint location,
5725 GLint x,
5726 GLint y,
5727 GLint z,
5728 GLint w)
5729{
5730 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5731}
5732
5733bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5734{
5735 return ValidateUniform(context, GL_INT_VEC4, location, count);
5736}
5737
5738bool ValidateUniformMatrix2fv(ValidationContext *context,
5739 GLint location,
5740 GLsizei count,
5741 GLboolean transpose,
5742 const GLfloat *value)
5743{
5744 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5745}
5746
5747bool ValidateUniformMatrix3fv(ValidationContext *context,
5748 GLint location,
5749 GLsizei count,
5750 GLboolean transpose,
5751 const GLfloat *value)
5752{
5753 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5754}
5755
5756bool ValidateUniformMatrix4fv(ValidationContext *context,
5757 GLint location,
5758 GLsizei count,
5759 GLboolean transpose,
5760 const GLfloat *value)
5761{
5762 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5763}
5764
5765bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5766{
5767 Program *programObject = GetValidProgram(context, program);
5768
5769 if (!programObject)
5770 {
5771 return false;
5772 }
5773
5774 return true;
5775}
5776
Jamie Madillc1d770e2017-04-13 17:31:24 -04005777bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5778{
5779 return ValidateVertexAttribIndex(context, index);
5780}
5781
5782bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5783{
5784 return ValidateVertexAttribIndex(context, index);
5785}
5786
5787bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5788{
5789 return ValidateVertexAttribIndex(context, index);
5790}
5791
5792bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5793{
5794 return ValidateVertexAttribIndex(context, index);
5795}
5796
5797bool ValidateVertexAttrib3f(ValidationContext *context,
5798 GLuint index,
5799 GLfloat x,
5800 GLfloat y,
5801 GLfloat z)
5802{
5803 return ValidateVertexAttribIndex(context, index);
5804}
5805
5806bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5807{
5808 return ValidateVertexAttribIndex(context, index);
5809}
5810
5811bool ValidateVertexAttrib4f(ValidationContext *context,
5812 GLuint index,
5813 GLfloat x,
5814 GLfloat y,
5815 GLfloat z,
5816 GLfloat w)
5817{
5818 return ValidateVertexAttribIndex(context, index);
5819}
5820
5821bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5822{
5823 return ValidateVertexAttribIndex(context, index);
5824}
5825
5826bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5827{
5828 if (width < 0 || height < 0)
5829 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005830 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005831 return false;
5832 }
5833
5834 return true;
5835}
5836
5837bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5838{
5839 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5840}
5841
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005842bool ValidateDrawElements(ValidationContext *context,
5843 GLenum mode,
5844 GLsizei count,
5845 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005846 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005847{
5848 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5849}
5850
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005851bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005852 GLenum target,
5853 GLenum attachment,
5854 GLenum pname,
5855 GLint *params)
5856{
5857 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5858 nullptr);
5859}
5860
5861bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5862{
5863 return ValidateGetProgramivBase(context, program, pname, nullptr);
5864}
5865
5866bool ValidateCopyTexImage2D(ValidationContext *context,
5867 GLenum target,
5868 GLint level,
5869 GLenum internalformat,
5870 GLint x,
5871 GLint y,
5872 GLsizei width,
5873 GLsizei height,
5874 GLint border)
5875{
5876 if (context->getClientMajorVersion() < 3)
5877 {
5878 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5879 0, x, y, width, height, border);
5880 }
5881
5882 ASSERT(context->getClientMajorVersion() == 3);
5883 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5884 0, x, y, width, height, border);
5885}
5886
5887bool ValidateCopyTexSubImage2D(Context *context,
5888 GLenum target,
5889 GLint level,
5890 GLint xoffset,
5891 GLint yoffset,
5892 GLint x,
5893 GLint y,
5894 GLsizei width,
5895 GLsizei height)
5896{
5897 if (context->getClientMajorVersion() < 3)
5898 {
5899 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5900 yoffset, x, y, width, height, 0);
5901 }
5902
5903 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5904 yoffset, 0, x, y, width, height, 0);
5905}
5906
5907bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5908{
5909 return ValidateGenOrDelete(context, n);
5910}
5911
5912bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5913{
5914 return ValidateGenOrDelete(context, n);
5915}
5916
5917bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5918{
5919 return ValidateGenOrDelete(context, n);
5920}
5921
5922bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5923{
5924 return ValidateGenOrDelete(context, n);
5925}
5926
5927bool ValidateDisable(Context *context, GLenum cap)
5928{
5929 if (!ValidCap(context, cap, false))
5930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005931 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005932 return false;
5933 }
5934
5935 return true;
5936}
5937
5938bool ValidateEnable(Context *context, GLenum cap)
5939{
5940 if (!ValidCap(context, cap, false))
5941 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 return false;
5944 }
5945
5946 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5947 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5948 {
5949 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005950 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005951
5952 // We also output an error message to the debugger window if tracing is active, so that
5953 // developers can see the error message.
5954 ERR() << errorMessage;
5955 return false;
5956 }
5957
5958 return true;
5959}
5960
5961bool ValidateFramebufferRenderbuffer(Context *context,
5962 GLenum target,
5963 GLenum attachment,
5964 GLenum renderbuffertarget,
5965 GLuint renderbuffer)
5966{
Geoff Lange8afa902017-09-27 15:00:43 -04005967 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005968 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005969 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5970 return false;
5971 }
5972
5973 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5974 {
5975 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005976 return false;
5977 }
5978
5979 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5980 renderbuffertarget, renderbuffer);
5981}
5982
5983bool ValidateFramebufferTexture2D(Context *context,
5984 GLenum target,
5985 GLenum attachment,
5986 GLenum textarget,
5987 GLuint texture,
5988 GLint level)
5989{
5990 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5991 // extension
5992 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5993 level != 0)
5994 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005995 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005996 return false;
5997 }
5998
5999 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6000 {
6001 return false;
6002 }
6003
6004 if (texture != 0)
6005 {
6006 gl::Texture *tex = context->getTexture(texture);
6007 ASSERT(tex);
6008
6009 const gl::Caps &caps = context->getCaps();
6010
6011 switch (textarget)
6012 {
6013 case GL_TEXTURE_2D:
6014 {
6015 if (level > gl::log2(caps.max2DTextureSize))
6016 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006017 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 return false;
6019 }
6020 if (tex->getTarget() != GL_TEXTURE_2D)
6021 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006022 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 return false;
6024 }
6025 }
6026 break;
6027
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006028 case GL_TEXTURE_RECTANGLE_ANGLE:
6029 {
6030 if (level != 0)
6031 {
6032 context->handleError(InvalidValue());
6033 return false;
6034 }
6035 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
6036 {
6037 context->handleError(InvalidOperation()
6038 << "Textarget must match the texture target type.");
6039 return false;
6040 }
6041 }
6042 break;
6043
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
6045 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
6046 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
6047 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
6048 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
6049 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
6050 {
6051 if (level > gl::log2(caps.maxCubeMapTextureSize))
6052 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006053 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006054 return false;
6055 }
6056 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
6057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006058 context->handleError(InvalidOperation()
6059 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006060 return false;
6061 }
6062 }
6063 break;
6064
6065 case GL_TEXTURE_2D_MULTISAMPLE:
6066 {
6067 if (context->getClientVersion() < ES_3_1)
6068 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006069 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 return false;
6071 }
6072
6073 if (level != 0)
6074 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006075 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 return false;
6077 }
6078 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
6079 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006080 context->handleError(InvalidOperation()
6081 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006082 return false;
6083 }
6084 }
6085 break;
6086
6087 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006088 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006089 return false;
6090 }
6091
6092 const Format &format = tex->getFormat(textarget, level);
6093 if (format.info->compressed)
6094 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006095 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 return false;
6097 }
6098 }
6099
6100 return true;
6101}
6102
6103bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6104{
6105 return ValidateGenOrDelete(context, n);
6106}
6107
6108bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6109{
6110 return ValidateGenOrDelete(context, n);
6111}
6112
6113bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6114{
6115 return ValidateGenOrDelete(context, n);
6116}
6117
6118bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6119{
6120 return ValidateGenOrDelete(context, n);
6121}
6122
6123bool ValidateGenerateMipmap(Context *context, GLenum target)
6124{
6125 if (!ValidTextureTarget(context, target))
6126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006127 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 return false;
6129 }
6130
6131 Texture *texture = context->getTargetTexture(target);
6132
6133 if (texture == nullptr)
6134 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006135 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 return false;
6137 }
6138
6139 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6140
6141 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6142 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6143 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6144 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006145 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 return false;
6147 }
6148
6149 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
Geoff Lang536eca12017-09-13 11:23:35 -04006150 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6151 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6152 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006153 {
6154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6155 return false;
6156 }
6157
Geoff Lang536eca12017-09-13 11:23:35 -04006158 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6159 bool formatUnsized = !format.sized;
6160 bool formatColorRenderableAndFilterable =
6161 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6162 format.renderSupport(context->getClientVersion(), context->getExtensions());
6163 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006164 {
Geoff Lang536eca12017-09-13 11:23:35 -04006165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006166 return false;
6167 }
6168
Geoff Lang536eca12017-09-13 11:23:35 -04006169 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6170 // generation
6171 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6172 {
6173 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6174 return false;
6175 }
6176
6177 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6178 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006179 bool supportsSRGBMipmapGeneration =
6180 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006181 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006182 {
Geoff Lang536eca12017-09-13 11:23:35 -04006183 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006184 return false;
6185 }
6186
6187 // Non-power of 2 ES2 check
6188 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6189 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6190 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6191 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006192 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6193 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006194 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006195 return false;
6196 }
6197
6198 // Cube completeness check
6199 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006201 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 return false;
6203 }
6204
6205 return true;
6206}
6207
6208bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006209 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006210 GLenum pname,
6211 GLint *params)
6212{
6213 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6214}
6215
6216bool ValidateGetRenderbufferParameteriv(Context *context,
6217 GLenum target,
6218 GLenum pname,
6219 GLint *params)
6220{
6221 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6222}
6223
6224bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6225{
6226 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6227}
6228
6229bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6230{
6231 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6232}
6233
6234bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6235{
6236 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6237}
6238
6239bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6240{
6241 return ValidateGetUniformBase(context, program, location);
6242}
6243
6244bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6245{
6246 return ValidateGetUniformBase(context, program, location);
6247}
6248
6249bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6250{
6251 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6252}
6253
6254bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6255{
6256 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6257}
6258
6259bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6260{
6261 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6262}
6263
6264bool ValidateIsEnabled(Context *context, GLenum cap)
6265{
6266 if (!ValidCap(context, cap, true))
6267 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006268 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006269 return false;
6270 }
6271
6272 return true;
6273}
6274
6275bool ValidateLinkProgram(Context *context, GLuint program)
6276{
6277 if (context->hasActiveTransformFeedback(program))
6278 {
6279 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006280 context->handleError(InvalidOperation() << "Cannot link program while program is "
6281 "associated with an active transform "
6282 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006283 return false;
6284 }
6285
6286 Program *programObject = GetValidProgram(context, program);
6287 if (!programObject)
6288 {
6289 return false;
6290 }
6291
6292 return true;
6293}
6294
Jamie Madill4928b7c2017-06-20 12:57:39 -04006295bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006296 GLint x,
6297 GLint y,
6298 GLsizei width,
6299 GLsizei height,
6300 GLenum format,
6301 GLenum type,
6302 void *pixels)
6303{
6304 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6305 nullptr, pixels);
6306}
6307
6308bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6309{
6310 return ValidateTexParameterBase(context, target, pname, -1, &param);
6311}
6312
6313bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6314{
6315 return ValidateTexParameterBase(context, target, pname, -1, params);
6316}
6317
6318bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6319{
6320 return ValidateTexParameterBase(context, target, pname, -1, &param);
6321}
6322
6323bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6324{
6325 return ValidateTexParameterBase(context, target, pname, -1, params);
6326}
6327
6328bool ValidateUseProgram(Context *context, GLuint program)
6329{
6330 if (program != 0)
6331 {
6332 Program *programObject = context->getProgram(program);
6333 if (!programObject)
6334 {
6335 // ES 3.1.0 section 7.3 page 72
6336 if (context->getShader(program))
6337 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006338 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006339 return false;
6340 }
6341 else
6342 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006343 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006344 return false;
6345 }
6346 }
6347 if (!programObject->isLinked())
6348 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006349 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006350 return false;
6351 }
6352 }
6353 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6354 {
6355 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006356 context
6357 ->handleError(InvalidOperation()
6358 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006359 return false;
6360 }
6361
6362 return true;
6363}
6364
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006365bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6366{
6367 if (!context->getExtensions().fence)
6368 {
6369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6370 return false;
6371 }
6372
6373 if (n < 0)
6374 {
6375 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6376 return false;
6377 }
6378
6379 return true;
6380}
6381
6382bool ValidateFinishFenceNV(Context *context, GLuint fence)
6383{
6384 if (!context->getExtensions().fence)
6385 {
6386 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6387 return false;
6388 }
6389
6390 FenceNV *fenceObject = context->getFenceNV(fence);
6391
6392 if (fenceObject == nullptr)
6393 {
6394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6395 return false;
6396 }
6397
6398 if (!fenceObject->isSet())
6399 {
6400 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6401 return false;
6402 }
6403
6404 return true;
6405}
6406
6407bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6408{
6409 if (!context->getExtensions().fence)
6410 {
6411 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6412 return false;
6413 }
6414
6415 if (n < 0)
6416 {
6417 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6418 return false;
6419 }
6420
6421 return true;
6422}
6423
6424bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6425{
6426 if (!context->getExtensions().fence)
6427 {
6428 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6429 return false;
6430 }
6431
6432 FenceNV *fenceObject = context->getFenceNV(fence);
6433
6434 if (fenceObject == nullptr)
6435 {
6436 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6437 return false;
6438 }
6439
6440 if (!fenceObject->isSet())
6441 {
6442 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6443 return false;
6444 }
6445
6446 switch (pname)
6447 {
6448 case GL_FENCE_STATUS_NV:
6449 case GL_FENCE_CONDITION_NV:
6450 break;
6451
6452 default:
6453 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6454 return false;
6455 }
6456
6457 return true;
6458}
6459
6460bool ValidateGetGraphicsResetStatusEXT(Context *context)
6461{
6462 if (!context->getExtensions().robustness)
6463 {
6464 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6465 return false;
6466 }
6467
6468 return true;
6469}
6470
6471bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6472 GLuint shader,
6473 GLsizei bufsize,
6474 GLsizei *length,
6475 GLchar *source)
6476{
6477 if (!context->getExtensions().translatedShaderSource)
6478 {
6479 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6480 return false;
6481 }
6482
6483 if (bufsize < 0)
6484 {
6485 context->handleError(InvalidValue());
6486 return false;
6487 }
6488
6489 Shader *shaderObject = context->getShader(shader);
6490
6491 if (!shaderObject)
6492 {
6493 context->handleError(InvalidOperation());
6494 return false;
6495 }
6496
6497 return true;
6498}
6499
6500bool ValidateIsFenceNV(Context *context, GLuint fence)
6501{
6502 if (!context->getExtensions().fence)
6503 {
6504 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6505 return false;
6506 }
6507
6508 return true;
6509}
6510
Jamie Madill007530e2017-12-28 14:27:04 -05006511bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6512{
6513 if (!context->getExtensions().fence)
6514 {
6515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6516 return false;
6517 }
6518
6519 if (condition != GL_ALL_COMPLETED_NV)
6520 {
6521 context->handleError(InvalidEnum());
6522 return false;
6523 }
6524
6525 FenceNV *fenceObject = context->getFenceNV(fence);
6526
6527 if (fenceObject == nullptr)
6528 {
6529 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6530 return false;
6531 }
6532
6533 return true;
6534}
6535
6536bool ValidateTestFenceNV(Context *context, GLuint fence)
6537{
6538 if (!context->getExtensions().fence)
6539 {
6540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6541 return false;
6542 }
6543
6544 FenceNV *fenceObject = context->getFenceNV(fence);
6545
6546 if (fenceObject == nullptr)
6547 {
6548 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6549 return false;
6550 }
6551
6552 if (fenceObject->isSet() != GL_TRUE)
6553 {
6554 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6555 return false;
6556 }
6557
6558 return true;
6559}
6560
6561bool ValidateTexStorage2DEXT(Context *context,
6562 GLenum target,
6563 GLsizei levels,
6564 GLenum internalformat,
6565 GLsizei width,
6566 GLsizei height)
6567{
6568 if (!context->getExtensions().textureStorage)
6569 {
6570 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6571 return false;
6572 }
6573
6574 if (context->getClientMajorVersion() < 3)
6575 {
6576 return ValidateES2TexStorageParameters(context, target, levels, internalformat, width,
6577 height);
6578 }
6579
6580 ASSERT(context->getClientMajorVersion() >= 3);
6581 return ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
6582 1);
6583}
6584
6585bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6586{
6587 if (!context->getExtensions().instancedArrays)
6588 {
6589 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6590 return false;
6591 }
6592
6593 if (index >= MAX_VERTEX_ATTRIBS)
6594 {
6595 context->handleError(InvalidValue());
6596 return false;
6597 }
6598
6599 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6600 {
6601 if (index == 0 && divisor != 0)
6602 {
6603 const char *errorMessage =
6604 "The current context doesn't support setting a non-zero divisor on the "
6605 "attribute with index zero. "
6606 "Please reorder the attributes in your vertex shader so that attribute zero "
6607 "can have a zero divisor.";
6608 context->handleError(InvalidOperation() << errorMessage);
6609
6610 // We also output an error message to the debugger window if tracing is active, so
6611 // that developers can see the error message.
6612 ERR() << errorMessage;
6613 return false;
6614 }
6615 }
6616
6617 return true;
6618}
6619
6620bool ValidateTexImage3DOES(Context *context,
6621 GLenum target,
6622 GLint level,
6623 GLenum internalformat,
6624 GLsizei width,
6625 GLsizei height,
6626 GLsizei depth,
6627 GLint border,
6628 GLenum format,
6629 GLenum type,
6630 const void *pixels)
6631{
6632 UNIMPLEMENTED(); // FIXME
6633 return false;
6634}
6635
6636bool ValidatePopGroupMarkerEXT(Context *context)
6637{
6638 if (!context->getExtensions().debugMarker)
6639 {
6640 // The debug marker calls should not set error state
6641 // However, it seems reasonable to set an error state if the extension is not enabled
6642 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6643 return false;
6644 }
6645
6646 return true;
6647}
6648
Jamie Madillc29968b2016-01-20 11:17:23 -05006649} // namespace gl