blob: 4bb3b9783420bc0ba7f84fe519e6b8c4a636b8b2 [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 }
Nico Weber41b072b2018-02-09 10:01:32 -05003331 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003332 case GL_PATH_MITER_LIMIT_CHROMIUM:
3333 if (value < 0.0f)
3334 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003335 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003336 return false;
3337 }
3338 break;
3339
3340 case GL_PATH_STROKE_BOUND_CHROMIUM:
3341 // no errors, only clamping.
3342 break;
3343
3344 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003345 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003346 return false;
3347 }
3348 return true;
3349}
3350
Jamie Madill007530e2017-12-28 14:27:04 -05003351bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3352{
3353 // TODO(jmadill): Use proper clamping cast.
3354 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3355}
3356
3357bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358{
3359 if (!context->getExtensions().pathRendering)
3360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003361 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003362 return false;
3363 }
3364
3365 if (!context->hasPath(path))
3366 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370 if (!value)
3371 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003372 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003373 return false;
3374 }
3375
3376 switch (pname)
3377 {
3378 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3379 case GL_PATH_END_CAPS_CHROMIUM:
3380 case GL_PATH_JOIN_STYLE_CHROMIUM:
3381 case GL_PATH_MITER_LIMIT_CHROMIUM:
3382 case GL_PATH_STROKE_BOUND_CHROMIUM:
3383 break;
3384
3385 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003386 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003387 return false;
3388 }
3389
3390 return true;
3391}
3392
Jamie Madill007530e2017-12-28 14:27:04 -05003393bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3394{
3395 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3396 reinterpret_cast<GLfloat *>(value));
3397}
3398
3399bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003400{
3401 if (!context->getExtensions().pathRendering)
3402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003403 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 return false;
3405 }
3406
3407 switch (func)
3408 {
3409 case GL_NEVER:
3410 case GL_ALWAYS:
3411 case GL_LESS:
3412 case GL_LEQUAL:
3413 case GL_EQUAL:
3414 case GL_GEQUAL:
3415 case GL_GREATER:
3416 case GL_NOTEQUAL:
3417 break;
3418 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003419 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420 return false;
3421 }
3422
3423 return true;
3424}
3425
3426// Note that the spec specifies that for the path drawing commands
3427// if the path object is not an existing path object the command
3428// does nothing and no error is generated.
3429// However if the path object exists but has not been specified any
3430// commands then an error is generated.
3431
Jamie Madill007530e2017-12-28 14:27:04 -05003432bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433{
3434 if (!context->getExtensions().pathRendering)
3435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003436 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003437 return false;
3438 }
3439 if (context->hasPath(path) && !context->hasPathData(path))
3440 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003441 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 switch (fillMode)
3446 {
3447 case GL_COUNT_UP_CHROMIUM:
3448 case GL_COUNT_DOWN_CHROMIUM:
3449 break;
3450 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452 return false;
3453 }
3454
3455 if (!isPow2(mask + 1))
3456 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003457 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 return true;
3462}
3463
Jamie Madill007530e2017-12-28 14:27:04 -05003464bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465{
3466 if (!context->getExtensions().pathRendering)
3467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003468 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003469 return false;
3470 }
3471 if (context->hasPath(path) && !context->hasPathData(path))
3472 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003473 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 return true;
3478}
3479
Jamie Madill007530e2017-12-28 14:27:04 -05003480bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003481{
3482 if (!context->getExtensions().pathRendering)
3483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003484 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003485 return false;
3486 }
3487 if (context->hasPath(path) && !context->hasPathData(path))
3488 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003490 return false;
3491 }
3492
3493 switch (coverMode)
3494 {
3495 case GL_CONVEX_HULL_CHROMIUM:
3496 case GL_BOUNDING_BOX_CHROMIUM:
3497 break;
3498 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003499 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 return false;
3501 }
3502 return true;
3503}
3504
Jamie Madill007530e2017-12-28 14:27:04 -05003505bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3506 GLuint path,
3507 GLenum fillMode,
3508 GLuint mask,
3509 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510{
Jamie Madill007530e2017-12-28 14:27:04 -05003511 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3512 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513}
3514
Jamie Madill007530e2017-12-28 14:27:04 -05003515bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3516 GLuint path,
3517 GLint reference,
3518 GLuint mask,
3519 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003520{
Jamie Madill007530e2017-12-28 14:27:04 -05003521 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3522 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523}
3524
Jamie Madill007530e2017-12-28 14:27:04 -05003525bool ValidateIsPathCHROMIUM(Context *context)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003526{
3527 if (!context->getExtensions().pathRendering)
3528 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003529 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 return false;
3531 }
3532 return true;
3533}
3534
Jamie Madill007530e2017-12-28 14:27:04 -05003535bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3536 GLsizei numPaths,
3537 GLenum pathNameType,
3538 const void *paths,
3539 GLuint pathBase,
3540 GLenum coverMode,
3541 GLenum transformType,
3542 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003543{
3544 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3545 transformType, transformValues))
3546 return false;
3547
3548 switch (coverMode)
3549 {
3550 case GL_CONVEX_HULL_CHROMIUM:
3551 case GL_BOUNDING_BOX_CHROMIUM:
3552 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3553 break;
3554 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003556 return false;
3557 }
3558
3559 return true;
3560}
3561
Jamie Madill007530e2017-12-28 14:27:04 -05003562bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3563 GLsizei numPaths,
3564 GLenum pathNameType,
3565 const void *paths,
3566 GLuint pathBase,
3567 GLenum coverMode,
3568 GLenum transformType,
3569 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003570{
3571 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3572 transformType, transformValues))
3573 return false;
3574
3575 switch (coverMode)
3576 {
3577 case GL_CONVEX_HULL_CHROMIUM:
3578 case GL_BOUNDING_BOX_CHROMIUM:
3579 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3580 break;
3581 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003583 return false;
3584 }
3585
3586 return true;
3587}
3588
Jamie Madill007530e2017-12-28 14:27:04 -05003589bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3590 GLsizei numPaths,
3591 GLenum pathNameType,
3592 const void *paths,
3593 GLuint pathBase,
3594 GLenum fillMode,
3595 GLuint mask,
3596 GLenum transformType,
3597 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003598{
3599
3600 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3601 transformType, transformValues))
3602 return false;
3603
3604 switch (fillMode)
3605 {
3606 case GL_COUNT_UP_CHROMIUM:
3607 case GL_COUNT_DOWN_CHROMIUM:
3608 break;
3609 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003611 return false;
3612 }
3613 if (!isPow2(mask + 1))
3614 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003615 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003616 return false;
3617 }
3618 return true;
3619}
3620
Jamie Madill007530e2017-12-28 14:27:04 -05003621bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3622 GLsizei numPaths,
3623 GLenum pathNameType,
3624 const void *paths,
3625 GLuint pathBase,
3626 GLint reference,
3627 GLuint mask,
3628 GLenum transformType,
3629 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003630{
3631 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3632 transformType, transformValues))
3633 return false;
3634
3635 // no more validation here.
3636
3637 return true;
3638}
3639
Jamie Madill007530e2017-12-28 14:27:04 -05003640bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3641 GLsizei numPaths,
3642 GLenum pathNameType,
3643 const void *paths,
3644 GLuint pathBase,
3645 GLenum fillMode,
3646 GLuint mask,
3647 GLenum coverMode,
3648 GLenum transformType,
3649 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003650{
3651 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3652 transformType, transformValues))
3653 return false;
3654
3655 switch (coverMode)
3656 {
3657 case GL_CONVEX_HULL_CHROMIUM:
3658 case GL_BOUNDING_BOX_CHROMIUM:
3659 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3660 break;
3661 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003662 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003663 return false;
3664 }
3665
3666 switch (fillMode)
3667 {
3668 case GL_COUNT_UP_CHROMIUM:
3669 case GL_COUNT_DOWN_CHROMIUM:
3670 break;
3671 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003672 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003673 return false;
3674 }
3675 if (!isPow2(mask + 1))
3676 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003677 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003678 return false;
3679 }
3680
3681 return true;
3682}
3683
Jamie Madill007530e2017-12-28 14:27:04 -05003684bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3685 GLsizei numPaths,
3686 GLenum pathNameType,
3687 const void *paths,
3688 GLuint pathBase,
3689 GLint reference,
3690 GLuint mask,
3691 GLenum coverMode,
3692 GLenum transformType,
3693 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003694{
3695 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3696 transformType, transformValues))
3697 return false;
3698
3699 switch (coverMode)
3700 {
3701 case GL_CONVEX_HULL_CHROMIUM:
3702 case GL_BOUNDING_BOX_CHROMIUM:
3703 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3704 break;
3705 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003706 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003707 return false;
3708 }
3709
3710 return true;
3711}
3712
Jamie Madill007530e2017-12-28 14:27:04 -05003713bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3714 GLuint program,
3715 GLint location,
3716 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003717{
3718 if (!context->getExtensions().pathRendering)
3719 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003720 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003721 return false;
3722 }
3723
3724 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3725 if (location >= MaxLocation)
3726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003727 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003728 return false;
3729 }
3730
3731 const auto *programObject = context->getProgram(program);
3732 if (!programObject)
3733 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003734 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003735 return false;
3736 }
3737
3738 if (!name)
3739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003740 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003741 return false;
3742 }
3743
3744 if (angle::BeginsWith(name, "gl_"))
3745 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003746 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 return true;
3751}
3752
Jamie Madill007530e2017-12-28 14:27:04 -05003753bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3754 GLuint program,
3755 GLint location,
3756 GLenum genMode,
3757 GLint components,
3758 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003759{
3760 if (!context->getExtensions().pathRendering)
3761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003762 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 const auto *programObject = context->getProgram(program);
3767 if (!programObject || programObject->isFlaggedForDeletion())
3768 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003769 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003770 return false;
3771 }
3772
3773 if (!programObject->isLinked())
3774 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003775 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003776 return false;
3777 }
3778
3779 switch (genMode)
3780 {
3781 case GL_NONE:
3782 if (components != 0)
3783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003784 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003785 return false;
3786 }
3787 break;
3788
3789 case GL_OBJECT_LINEAR_CHROMIUM:
3790 case GL_EYE_LINEAR_CHROMIUM:
3791 case GL_CONSTANT_CHROMIUM:
3792 if (components < 1 || components > 4)
3793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003794 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003795 return false;
3796 }
3797 if (!coeffs)
3798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003799 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003800 return false;
3801 }
3802 break;
3803
3804 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003805 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 // If the location is -1 then the command is silently ignored
3810 // and no further validation is needed.
3811 if (location == -1)
3812 return true;
3813
Jamie Madillbd044ed2017-06-05 12:59:21 -04003814 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003815
3816 if (!binding.valid)
3817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003818 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003819 return false;
3820 }
3821
3822 if (binding.type != GL_NONE)
3823 {
3824 GLint expectedComponents = 0;
3825 switch (binding.type)
3826 {
3827 case GL_FLOAT:
3828 expectedComponents = 1;
3829 break;
3830 case GL_FLOAT_VEC2:
3831 expectedComponents = 2;
3832 break;
3833 case GL_FLOAT_VEC3:
3834 expectedComponents = 3;
3835 break;
3836 case GL_FLOAT_VEC4:
3837 expectedComponents = 4;
3838 break;
3839 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003840 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003841 InvalidOperation()
3842 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003843 return false;
3844 }
3845 if (expectedComponents != components && genMode != GL_NONE)
3846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003847 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003848 return false;
3849 }
3850 }
3851 return true;
3852}
3853
Geoff Lang97073d12016-04-20 10:42:34 -07003854bool ValidateCopyTextureCHROMIUM(Context *context,
3855 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003856 GLint sourceLevel,
3857 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003858 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003859 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003860 GLint internalFormat,
3861 GLenum destType,
3862 GLboolean unpackFlipY,
3863 GLboolean unpackPremultiplyAlpha,
3864 GLboolean unpackUnmultiplyAlpha)
3865{
3866 if (!context->getExtensions().copyTexture)
3867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003868 context->handleError(InvalidOperation()
3869 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
Geoff Lang4f0e0032017-05-01 16:04:35 -04003873 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003874 if (source == nullptr)
3875 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003876 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003877 return false;
3878 }
3879
3880 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003882 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003883 return false;
3884 }
3885
3886 GLenum sourceTarget = source->getTarget();
3887 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003888
3889 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003891 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003892 return false;
3893 }
3894
Geoff Lang4f0e0032017-05-01 16:04:35 -04003895 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3896 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3897 if (sourceWidth == 0 || sourceHeight == 0)
3898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003899 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003900 return false;
3901 }
3902
3903 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3904 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003905 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003906 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003907 return false;
3908 }
3909
Geoff Lang63458a32017-10-30 15:16:53 -04003910 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3911 {
3912 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3913 return false;
3914 }
3915
Geoff Lang4f0e0032017-05-01 16:04:35 -04003916 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003917 if (dest == nullptr)
3918 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003919 context->handleError(InvalidValue()
3920 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003921 return false;
3922 }
3923
Geoff Lang4f0e0032017-05-01 16:04:35 -04003924 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003925 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003926 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003927 return false;
3928 }
3929
Geoff Lang4f0e0032017-05-01 16:04:35 -04003930 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3931 sourceHeight))
3932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003933 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003934 return false;
3935 }
3936
Geoff Lang97073d12016-04-20 10:42:34 -07003937 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3938 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003939 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
Geoff Lang4f0e0032017-05-01 16:04:35 -04003943 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003945 context->handleError(
3946 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003947 return false;
3948 }
3949
Geoff Lang97073d12016-04-20 10:42:34 -07003950 if (dest->getImmutableFormat())
3951 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003952 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003953 return false;
3954 }
3955
3956 return true;
3957}
3958
3959bool ValidateCopySubTextureCHROMIUM(Context *context,
3960 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003961 GLint sourceLevel,
3962 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003963 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003964 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003965 GLint xoffset,
3966 GLint yoffset,
3967 GLint x,
3968 GLint y,
3969 GLsizei width,
3970 GLsizei height,
3971 GLboolean unpackFlipY,
3972 GLboolean unpackPremultiplyAlpha,
3973 GLboolean unpackUnmultiplyAlpha)
3974{
3975 if (!context->getExtensions().copyTexture)
3976 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003977 context->handleError(InvalidOperation()
3978 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003979 return false;
3980 }
3981
Geoff Lang4f0e0032017-05-01 16:04:35 -04003982 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003983 if (source == nullptr)
3984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003985 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
3989 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
3995 GLenum sourceTarget = source->getTarget();
3996 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003997
3998 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3999 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004000 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001 return false;
4002 }
4003
4004 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4005 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004007 context->handleError(InvalidValue()
4008 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004009 return false;
4010 }
4011
4012 if (x < 0 || y < 0)
4013 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004014 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004015 return false;
4016 }
4017
4018 if (width < 0 || height < 0)
4019 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004020 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004021 return false;
4022 }
4023
Geoff Lang4f0e0032017-05-01 16:04:35 -04004024 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4025 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004026 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004027 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004028 return false;
4029 }
4030
Geoff Lang4f0e0032017-05-01 16:04:35 -04004031 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4032 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004034 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Geoff Lang63458a32017-10-30 15:16:53 -04004038 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4039 {
4040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4041 return false;
4042 }
4043
Geoff Lang4f0e0032017-05-01 16:04:35 -04004044 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004045 if (dest == nullptr)
4046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004047 context->handleError(InvalidValue()
4048 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
Geoff Lang4f0e0032017-05-01 16:04:35 -04004052 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004054 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004055 return false;
4056 }
4057
Geoff Lang4f0e0032017-05-01 16:04:35 -04004058 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07004059 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004060 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004061 return false;
4062 }
4063
Geoff Lang4f0e0032017-05-01 16:04:35 -04004064 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4065 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004066 context
4067 ->handleError(InvalidOperation()
4068 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004069 return false;
4070 }
4071
4072 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4073 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004075 context->handleError(InvalidOperation()
4076 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004077 return false;
4078 }
4079
4080 if (xoffset < 0 || yoffset < 0)
4081 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004082 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Geoff Lang4f0e0032017-05-01 16:04:35 -04004086 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4087 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004089 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004090 return false;
4091 }
4092
4093 return true;
4094}
4095
Geoff Lang47110bf2016-04-20 11:13:22 -07004096bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4097{
4098 if (!context->getExtensions().copyCompressedTexture)
4099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004100 context->handleError(InvalidOperation()
4101 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004102 return false;
4103 }
4104
4105 const gl::Texture *source = context->getTexture(sourceId);
4106 if (source == nullptr)
4107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004108 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004109 return false;
4110 }
4111
4112 if (source->getTarget() != GL_TEXTURE_2D)
4113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004114 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004115 return false;
4116 }
4117
4118 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4119 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004120 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004121 return false;
4122 }
4123
4124 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4125 if (!sourceFormat.info->compressed)
4126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004127 context->handleError(InvalidOperation()
4128 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004129 return false;
4130 }
4131
4132 const gl::Texture *dest = context->getTexture(destId);
4133 if (dest == nullptr)
4134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004135 context->handleError(InvalidValue()
4136 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004137 return false;
4138 }
4139
4140 if (dest->getTarget() != GL_TEXTURE_2D)
4141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004142 context->handleError(InvalidValue()
4143 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004144 return false;
4145 }
4146
4147 if (dest->getImmutableFormat())
4148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004149 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004150 return false;
4151 }
4152
4153 return true;
4154}
4155
Martin Radev4c4c8e72016-08-04 12:25:34 +03004156bool ValidateCreateShader(Context *context, GLenum type)
4157{
4158 switch (type)
4159 {
4160 case GL_VERTEX_SHADER:
4161 case GL_FRAGMENT_SHADER:
4162 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004163
Martin Radev4c4c8e72016-08-04 12:25:34 +03004164 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004165 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004166 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004167 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004168 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004169 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004170 break;
4171
Jiawei Shao89be29a2017-11-06 14:36:45 +08004172 case GL_GEOMETRY_SHADER_EXT:
4173 if (!context->getExtensions().geometryShader)
4174 {
4175 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4176 return false;
4177 }
4178 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004179 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004180 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004181 return false;
4182 }
Jamie Madill29639852016-09-02 15:00:09 -04004183
4184 return true;
4185}
4186
4187bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004188 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004189 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004190 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004191 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004192{
4193 if (size < 0)
4194 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004195 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004196 return false;
4197 }
4198
4199 switch (usage)
4200 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004201 case BufferUsage::StreamDraw:
4202 case BufferUsage::StaticDraw:
4203 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004204 break;
4205
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004206 case BufferUsage::StreamRead:
4207 case BufferUsage::StaticRead:
4208 case BufferUsage::DynamicRead:
4209 case BufferUsage::StreamCopy:
4210 case BufferUsage::StaticCopy:
4211 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004212 if (context->getClientMajorVersion() < 3)
4213 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004214 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004215 return false;
4216 }
4217 break;
4218
4219 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004220 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004221 return false;
4222 }
4223
Corentin Walleze4477002017-12-01 14:39:58 -05004224 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004225 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004226 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004227 return false;
4228 }
4229
4230 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4231
4232 if (!buffer)
4233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004234 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004235 return false;
4236 }
4237
4238 return true;
4239}
4240
4241bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004242 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004243 GLintptr offset,
4244 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004245 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004246{
Brandon Jones6cad5662017-06-14 13:25:13 -07004247 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004248 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004249 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4250 return false;
4251 }
4252
4253 if (offset < 0)
4254 {
4255 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004256 return false;
4257 }
4258
Corentin Walleze4477002017-12-01 14:39:58 -05004259 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004260 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004261 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004262 return false;
4263 }
4264
4265 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4266
4267 if (!buffer)
4268 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004269 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004270 return false;
4271 }
4272
4273 if (buffer->isMapped())
4274 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004275 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004276 return false;
4277 }
4278
4279 // Check for possible overflow of size + offset
4280 angle::CheckedNumeric<size_t> checkedSize(size);
4281 checkedSize += offset;
4282 if (!checkedSize.IsValid())
4283 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004284 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004285 return false;
4286 }
4287
4288 if (size + offset > buffer->getSize())
4289 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004290 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004291 return false;
4292 }
4293
Martin Radev4c4c8e72016-08-04 12:25:34 +03004294 return true;
4295}
4296
Geoff Lang111a99e2017-10-17 10:58:41 -04004297bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004298{
Geoff Langc339c4e2016-11-29 10:37:36 -05004299 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004300 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004301 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004302 return false;
4303 }
4304
Geoff Lang111a99e2017-10-17 10:58:41 -04004305 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004306 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004307 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004308 return false;
4309 }
4310
4311 return true;
4312}
4313
Jamie Madillef300b12016-10-07 15:12:09 -04004314bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4315{
4316 if (texture < GL_TEXTURE0 ||
4317 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4318 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004319 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004320 return false;
4321 }
4322
4323 return true;
4324}
4325
4326bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4327{
4328 Program *programObject = GetValidProgram(context, program);
4329 if (!programObject)
4330 {
4331 return false;
4332 }
4333
4334 Shader *shaderObject = GetValidShader(context, shader);
4335 if (!shaderObject)
4336 {
4337 return false;
4338 }
4339
4340 switch (shaderObject->getType())
4341 {
4342 case GL_VERTEX_SHADER:
4343 {
4344 if (programObject->getAttachedVertexShader())
4345 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004347 return false;
4348 }
4349 break;
4350 }
4351 case GL_FRAGMENT_SHADER:
4352 {
4353 if (programObject->getAttachedFragmentShader())
4354 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004355 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004356 return false;
4357 }
4358 break;
4359 }
4360 case GL_COMPUTE_SHADER:
4361 {
4362 if (programObject->getAttachedComputeShader())
4363 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004365 return false;
4366 }
4367 break;
4368 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004369 case GL_GEOMETRY_SHADER_EXT:
4370 {
4371 if (programObject->getAttachedGeometryShader())
4372 {
4373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4374 return false;
4375 }
4376 break;
4377 }
Jamie Madillef300b12016-10-07 15:12:09 -04004378 default:
4379 UNREACHABLE();
4380 break;
4381 }
4382
4383 return true;
4384}
4385
Jamie Madill01a80ee2016-11-07 12:06:18 -05004386bool ValidateBindAttribLocation(ValidationContext *context,
4387 GLuint program,
4388 GLuint index,
4389 const GLchar *name)
4390{
4391 if (index >= MAX_VERTEX_ATTRIBS)
4392 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004393 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004394 return false;
4395 }
4396
4397 if (strncmp(name, "gl_", 3) == 0)
4398 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004400 return false;
4401 }
4402
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004403 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004404 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004405 const size_t length = strlen(name);
4406
4407 if (!IsValidESSLString(name, length))
4408 {
4409 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4410 // for shader-related entry points
4411 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4412 return false;
4413 }
4414
4415 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4416 {
4417 return false;
4418 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004419 }
4420
Jamie Madill01a80ee2016-11-07 12:06:18 -05004421 return GetValidProgram(context, program) != nullptr;
4422}
4423
Corentin Wallez336129f2017-10-17 15:55:40 -04004424bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004425{
Corentin Walleze4477002017-12-01 14:39:58 -05004426 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004427 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004428 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004429 return false;
4430 }
4431
4432 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4433 !context->isBufferGenerated(buffer))
4434 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004435 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 return false;
4437 }
4438
4439 return true;
4440}
4441
4442bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4443{
Geoff Lange8afa902017-09-27 15:00:43 -04004444 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004446 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004447 return false;
4448 }
4449
4450 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4451 !context->isFramebufferGenerated(framebuffer))
4452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004453 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004454 return false;
4455 }
4456
4457 return true;
4458}
4459
4460bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4461{
4462 if (target != GL_RENDERBUFFER)
4463 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004464 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004465 return false;
4466 }
4467
4468 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4469 !context->isRenderbufferGenerated(renderbuffer))
4470 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004471 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004472 return false;
4473 }
4474
4475 return true;
4476}
4477
Geoff Lang50cac572017-09-26 17:37:43 -04004478static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004479{
4480 switch (mode)
4481 {
4482 case GL_FUNC_ADD:
4483 case GL_FUNC_SUBTRACT:
4484 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004485 return true;
4486
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004487 case GL_MIN:
4488 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004489 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004490
4491 default:
4492 return false;
4493 }
4494}
4495
Jamie Madillc1d770e2017-04-13 17:31:24 -04004496bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004497 GLfloat red,
4498 GLfloat green,
4499 GLfloat blue,
4500 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004501{
4502 return true;
4503}
4504
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4506{
Geoff Lang50cac572017-09-26 17:37:43 -04004507 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004509 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510 return false;
4511 }
4512
4513 return true;
4514}
4515
4516bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4517{
Geoff Lang50cac572017-09-26 17:37:43 -04004518 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004519 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004520 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004521 return false;
4522 }
4523
Geoff Lang50cac572017-09-26 17:37:43 -04004524 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004526 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004527 return false;
4528 }
4529
4530 return true;
4531}
4532
4533bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4534{
4535 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4536}
4537
4538static bool ValidSrcBlendFunc(GLenum srcBlend)
4539{
4540 switch (srcBlend)
4541 {
4542 case GL_ZERO:
4543 case GL_ONE:
4544 case GL_SRC_COLOR:
4545 case GL_ONE_MINUS_SRC_COLOR:
4546 case GL_DST_COLOR:
4547 case GL_ONE_MINUS_DST_COLOR:
4548 case GL_SRC_ALPHA:
4549 case GL_ONE_MINUS_SRC_ALPHA:
4550 case GL_DST_ALPHA:
4551 case GL_ONE_MINUS_DST_ALPHA:
4552 case GL_CONSTANT_COLOR:
4553 case GL_ONE_MINUS_CONSTANT_COLOR:
4554 case GL_CONSTANT_ALPHA:
4555 case GL_ONE_MINUS_CONSTANT_ALPHA:
4556 case GL_SRC_ALPHA_SATURATE:
4557 return true;
4558
4559 default:
4560 return false;
4561 }
4562}
4563
4564static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4565{
4566 switch (dstBlend)
4567 {
4568 case GL_ZERO:
4569 case GL_ONE:
4570 case GL_SRC_COLOR:
4571 case GL_ONE_MINUS_SRC_COLOR:
4572 case GL_DST_COLOR:
4573 case GL_ONE_MINUS_DST_COLOR:
4574 case GL_SRC_ALPHA:
4575 case GL_ONE_MINUS_SRC_ALPHA:
4576 case GL_DST_ALPHA:
4577 case GL_ONE_MINUS_DST_ALPHA:
4578 case GL_CONSTANT_COLOR:
4579 case GL_ONE_MINUS_CONSTANT_COLOR:
4580 case GL_CONSTANT_ALPHA:
4581 case GL_ONE_MINUS_CONSTANT_ALPHA:
4582 return true;
4583
4584 case GL_SRC_ALPHA_SATURATE:
4585 return (contextMajorVersion >= 3);
4586
4587 default:
4588 return false;
4589 }
4590}
4591
4592bool ValidateBlendFuncSeparate(ValidationContext *context,
4593 GLenum srcRGB,
4594 GLenum dstRGB,
4595 GLenum srcAlpha,
4596 GLenum dstAlpha)
4597{
4598 if (!ValidSrcBlendFunc(srcRGB))
4599 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004600 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004601 return false;
4602 }
4603
4604 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4605 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004606 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004607 return false;
4608 }
4609
4610 if (!ValidSrcBlendFunc(srcAlpha))
4611 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 return false;
4614 }
4615
4616 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4617 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004618 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004619 return false;
4620 }
4621
Frank Henigman146e8a12017-03-02 23:22:37 -05004622 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4623 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 {
4625 bool constantColorUsed =
4626 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4627 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4628
4629 bool constantAlphaUsed =
4630 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4631 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4632
4633 if (constantColorUsed && constantAlphaUsed)
4634 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004635 const char *msg;
4636 if (context->getExtensions().webglCompatibility)
4637 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004638 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004639 }
4640 else
4641 {
4642 msg =
4643 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4644 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4645 "implementation.";
4646 ERR() << msg;
4647 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004648 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004649 return false;
4650 }
4651 }
4652
4653 return true;
4654}
4655
Geoff Langc339c4e2016-11-29 10:37:36 -05004656bool ValidateGetString(Context *context, GLenum name)
4657{
4658 switch (name)
4659 {
4660 case GL_VENDOR:
4661 case GL_RENDERER:
4662 case GL_VERSION:
4663 case GL_SHADING_LANGUAGE_VERSION:
4664 case GL_EXTENSIONS:
4665 break;
4666
4667 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4668 if (!context->getExtensions().requestExtension)
4669 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004670 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004671 return false;
4672 }
4673 break;
4674
4675 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004676 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004677 return false;
4678 }
4679
4680 return true;
4681}
4682
Geoff Lang47c48082016-12-07 15:38:13 -05004683bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4684{
4685 if (width <= 0.0f || isNaN(width))
4686 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004687 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004688 return false;
4689 }
4690
4691 return true;
4692}
4693
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004694bool ValidateVertexAttribPointer(ValidationContext *context,
4695 GLuint index,
4696 GLint size,
4697 GLenum type,
4698 GLboolean normalized,
4699 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004700 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701{
Shao80957d92017-02-20 21:25:59 +08004702 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004703 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004704 return false;
4705 }
4706
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004707 if (stride < 0)
4708 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004709 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004710 return false;
4711 }
4712
Shao80957d92017-02-20 21:25:59 +08004713 const Caps &caps = context->getCaps();
4714 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 {
Shao80957d92017-02-20 21:25:59 +08004716 if (stride > caps.maxVertexAttribStride)
4717 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004718 context->handleError(InvalidValue()
4719 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004720 return false;
4721 }
4722
4723 if (index >= caps.maxVertexAttribBindings)
4724 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004725 context->handleError(InvalidValue()
4726 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004727 return false;
4728 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 }
4730
4731 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4732 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4733 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4734 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004735 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4736 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004737 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4738 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004740 context
4741 ->handleError(InvalidOperation()
4742 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 return false;
4744 }
4745
4746 if (context->getExtensions().webglCompatibility)
4747 {
4748 // WebGL 1.0 [Section 6.14] Fixed point support
4749 // The WebGL API does not support the GL_FIXED data type.
4750 if (type == GL_FIXED)
4751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004752 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004753 return false;
4754 }
4755
Geoff Lang2d62ab72017-03-23 16:54:40 -04004756 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004757 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 return false;
4759 }
4760 }
4761
4762 return true;
4763}
4764
Jamie Madill876429b2017-04-20 15:46:24 -04004765bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004766{
4767 if (context->getExtensions().webglCompatibility && zNear > zFar)
4768 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004769 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004770 return false;
4771 }
4772
4773 return true;
4774}
4775
Jamie Madille8fb6402017-02-14 17:56:40 -05004776bool ValidateRenderbufferStorage(ValidationContext *context,
4777 GLenum target,
4778 GLenum internalformat,
4779 GLsizei width,
4780 GLsizei height)
4781{
4782 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4783 height);
4784}
4785
4786bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4787 GLenum target,
4788 GLsizei samples,
4789 GLenum internalformat,
4790 GLsizei width,
4791 GLsizei height)
4792{
4793 if (!context->getExtensions().framebufferMultisample)
4794 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004795 context->handleError(InvalidOperation()
4796 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004797 return false;
4798 }
4799
4800 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4801 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4802 // generated.
4803 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004805 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004806 return false;
4807 }
4808
4809 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4810 // the specified storage. This is different than ES 3.0 in which a sample number higher
4811 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4812 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4813 if (context->getClientMajorVersion() >= 3)
4814 {
4815 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4816 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4817 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004818 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004819 return false;
4820 }
4821 }
4822
4823 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4824 width, height);
4825}
4826
Jamie Madillc1d770e2017-04-13 17:31:24 -04004827bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4828{
Geoff Lange8afa902017-09-27 15:00:43 -04004829 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004831 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004832 return false;
4833 }
4834
4835 return true;
4836}
4837
4838bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004839 GLfloat red,
4840 GLfloat green,
4841 GLfloat blue,
4842 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843{
4844 return true;
4845}
4846
Jamie Madill876429b2017-04-20 15:46:24 -04004847bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004848{
4849 return true;
4850}
4851
4852bool ValidateClearStencil(ValidationContext *context, GLint s)
4853{
4854 return true;
4855}
4856
4857bool ValidateColorMask(ValidationContext *context,
4858 GLboolean red,
4859 GLboolean green,
4860 GLboolean blue,
4861 GLboolean alpha)
4862{
4863 return true;
4864}
4865
4866bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4867{
4868 return true;
4869}
4870
4871bool ValidateCreateProgram(ValidationContext *context)
4872{
4873 return true;
4874}
4875
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004876bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877{
4878 switch (mode)
4879 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004880 case CullFaceMode::Front:
4881 case CullFaceMode::Back:
4882 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004883 break;
4884
4885 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004886 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004887 return false;
4888 }
4889
4890 return true;
4891}
4892
4893bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4894{
4895 if (program == 0)
4896 {
4897 return false;
4898 }
4899
4900 if (!context->getProgram(program))
4901 {
4902 if (context->getShader(program))
4903 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004904 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905 return false;
4906 }
4907 else
4908 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004909 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004910 return false;
4911 }
4912 }
4913
4914 return true;
4915}
4916
4917bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4918{
4919 if (shader == 0)
4920 {
4921 return false;
4922 }
4923
4924 if (!context->getShader(shader))
4925 {
4926 if (context->getProgram(shader))
4927 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004928 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004929 return false;
4930 }
4931 else
4932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004933 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004934 return false;
4935 }
4936 }
4937
4938 return true;
4939}
4940
4941bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4942{
4943 switch (func)
4944 {
4945 case GL_NEVER:
4946 case GL_ALWAYS:
4947 case GL_LESS:
4948 case GL_LEQUAL:
4949 case GL_EQUAL:
4950 case GL_GREATER:
4951 case GL_GEQUAL:
4952 case GL_NOTEQUAL:
4953 break;
4954
4955 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004956 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957 return false;
4958 }
4959
4960 return true;
4961}
4962
4963bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4964{
4965 return true;
4966}
4967
4968bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4969{
4970 Program *programObject = GetValidProgram(context, program);
4971 if (!programObject)
4972 {
4973 return false;
4974 }
4975
4976 Shader *shaderObject = GetValidShader(context, shader);
4977 if (!shaderObject)
4978 {
4979 return false;
4980 }
4981
4982 const Shader *attachedShader = nullptr;
4983
4984 switch (shaderObject->getType())
4985 {
4986 case GL_VERTEX_SHADER:
4987 {
4988 attachedShader = programObject->getAttachedVertexShader();
4989 break;
4990 }
4991 case GL_FRAGMENT_SHADER:
4992 {
4993 attachedShader = programObject->getAttachedFragmentShader();
4994 break;
4995 }
4996 case GL_COMPUTE_SHADER:
4997 {
4998 attachedShader = programObject->getAttachedComputeShader();
4999 break;
5000 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08005001 case GL_GEOMETRY_SHADER_EXT:
5002 {
5003 attachedShader = programObject->getAttachedGeometryShader();
5004 break;
5005 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04005006 default:
5007 UNREACHABLE();
5008 return false;
5009 }
5010
5011 if (attachedShader != shaderObject)
5012 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005013 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005014 return false;
5015 }
5016
5017 return true;
5018}
5019
5020bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5021{
5022 if (index >= MAX_VERTEX_ATTRIBS)
5023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005024 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 return true;
5029}
5030
5031bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5032{
5033 if (index >= MAX_VERTEX_ATTRIBS)
5034 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005035 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005036 return false;
5037 }
5038
5039 return true;
5040}
5041
5042bool ValidateFinish(ValidationContext *context)
5043{
5044 return true;
5045}
5046
5047bool ValidateFlush(ValidationContext *context)
5048{
5049 return true;
5050}
5051
5052bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5053{
5054 switch (mode)
5055 {
5056 case GL_CW:
5057 case GL_CCW:
5058 break;
5059 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005060 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005061 return false;
5062 }
5063
5064 return true;
5065}
5066
5067bool ValidateGetActiveAttrib(ValidationContext *context,
5068 GLuint program,
5069 GLuint index,
5070 GLsizei bufsize,
5071 GLsizei *length,
5072 GLint *size,
5073 GLenum *type,
5074 GLchar *name)
5075{
5076 if (bufsize < 0)
5077 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005078 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005079 return false;
5080 }
5081
5082 Program *programObject = GetValidProgram(context, program);
5083
5084 if (!programObject)
5085 {
5086 return false;
5087 }
5088
5089 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5090 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005091 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005092 return false;
5093 }
5094
5095 return true;
5096}
5097
5098bool ValidateGetActiveUniform(ValidationContext *context,
5099 GLuint program,
5100 GLuint index,
5101 GLsizei bufsize,
5102 GLsizei *length,
5103 GLint *size,
5104 GLenum *type,
5105 GLchar *name)
5106{
5107 if (bufsize < 0)
5108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005109 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 return false;
5111 }
5112
5113 Program *programObject = GetValidProgram(context, program);
5114
5115 if (!programObject)
5116 {
5117 return false;
5118 }
5119
5120 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5121 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005122 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005123 return false;
5124 }
5125
5126 return true;
5127}
5128
5129bool ValidateGetAttachedShaders(ValidationContext *context,
5130 GLuint program,
5131 GLsizei maxcount,
5132 GLsizei *count,
5133 GLuint *shaders)
5134{
5135 if (maxcount < 0)
5136 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005137 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005138 return false;
5139 }
5140
5141 Program *programObject = GetValidProgram(context, program);
5142
5143 if (!programObject)
5144 {
5145 return false;
5146 }
5147
5148 return true;
5149}
5150
5151bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5152{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005153 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5154 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005155 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005157 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005158 return false;
5159 }
5160
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 Program *programObject = GetValidProgram(context, program);
5162
5163 if (!programObject)
5164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005166 return false;
5167 }
5168
5169 if (!programObject->isLinked())
5170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005171 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005172 return false;
5173 }
5174
5175 return true;
5176}
5177
5178bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5179{
5180 GLenum nativeType;
5181 unsigned int numParams = 0;
5182 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5183}
5184
5185bool ValidateGetError(ValidationContext *context)
5186{
5187 return true;
5188}
5189
5190bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5191{
5192 GLenum nativeType;
5193 unsigned int numParams = 0;
5194 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5195}
5196
5197bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5198{
5199 GLenum nativeType;
5200 unsigned int numParams = 0;
5201 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5202}
5203
5204bool ValidateGetProgramInfoLog(ValidationContext *context,
5205 GLuint program,
5206 GLsizei bufsize,
5207 GLsizei *length,
5208 GLchar *infolog)
5209{
5210 if (bufsize < 0)
5211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005212 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 return false;
5214 }
5215
5216 Program *programObject = GetValidProgram(context, program);
5217 if (!programObject)
5218 {
5219 return false;
5220 }
5221
5222 return true;
5223}
5224
5225bool ValidateGetShaderInfoLog(ValidationContext *context,
5226 GLuint shader,
5227 GLsizei bufsize,
5228 GLsizei *length,
5229 GLchar *infolog)
5230{
5231 if (bufsize < 0)
5232 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005233 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005234 return false;
5235 }
5236
5237 Shader *shaderObject = GetValidShader(context, shader);
5238 if (!shaderObject)
5239 {
5240 return false;
5241 }
5242
5243 return true;
5244}
5245
5246bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5247 GLenum shadertype,
5248 GLenum precisiontype,
5249 GLint *range,
5250 GLint *precision)
5251{
5252 switch (shadertype)
5253 {
5254 case GL_VERTEX_SHADER:
5255 case GL_FRAGMENT_SHADER:
5256 break;
5257 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005258 context->handleError(InvalidOperation()
5259 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005260 return false;
5261 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005262 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005263 return false;
5264 }
5265
5266 switch (precisiontype)
5267 {
5268 case GL_LOW_FLOAT:
5269 case GL_MEDIUM_FLOAT:
5270 case GL_HIGH_FLOAT:
5271 case GL_LOW_INT:
5272 case GL_MEDIUM_INT:
5273 case GL_HIGH_INT:
5274 break;
5275
5276 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005277 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 }
5280
5281 return true;
5282}
5283
5284bool ValidateGetShaderSource(ValidationContext *context,
5285 GLuint shader,
5286 GLsizei bufsize,
5287 GLsizei *length,
5288 GLchar *source)
5289{
5290 if (bufsize < 0)
5291 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005292 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005293 return false;
5294 }
5295
5296 Shader *shaderObject = GetValidShader(context, shader);
5297 if (!shaderObject)
5298 {
5299 return false;
5300 }
5301
5302 return true;
5303}
5304
5305bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5306{
5307 if (strstr(name, "gl_") == name)
5308 {
5309 return false;
5310 }
5311
Geoff Langfc32e8b2017-05-31 14:16:59 -04005312 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5313 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005314 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005316 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005317 return false;
5318 }
5319
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320 Program *programObject = GetValidProgram(context, program);
5321
5322 if (!programObject)
5323 {
5324 return false;
5325 }
5326
5327 if (!programObject->isLinked())
5328 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005329 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330 return false;
5331 }
5332
5333 return true;
5334}
5335
5336bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5337{
5338 switch (mode)
5339 {
5340 case GL_FASTEST:
5341 case GL_NICEST:
5342 case GL_DONT_CARE:
5343 break;
5344
5345 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005346 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 return false;
5348 }
5349
5350 switch (target)
5351 {
5352 case GL_GENERATE_MIPMAP_HINT:
5353 break;
5354
Geoff Lange7bd2182017-06-16 16:13:13 -04005355 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5356 if (context->getClientVersion() < ES_3_0 &&
5357 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005359 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360 return false;
5361 }
5362 break;
5363
5364 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005365 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 return false;
5367 }
5368
5369 return true;
5370}
5371
5372bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5373{
5374 return true;
5375}
5376
5377bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5378{
5379 return true;
5380}
5381
5382bool ValidateIsProgram(ValidationContext *context, GLuint program)
5383{
5384 return true;
5385}
5386
5387bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5388{
5389 return true;
5390}
5391
5392bool ValidateIsShader(ValidationContext *context, GLuint shader)
5393{
5394 return true;
5395}
5396
5397bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5398{
5399 return true;
5400}
5401
5402bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5403{
5404 if (context->getClientMajorVersion() < 3)
5405 {
5406 switch (pname)
5407 {
5408 case GL_UNPACK_IMAGE_HEIGHT:
5409 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005410 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005411 return false;
5412
5413 case GL_UNPACK_ROW_LENGTH:
5414 case GL_UNPACK_SKIP_ROWS:
5415 case GL_UNPACK_SKIP_PIXELS:
5416 if (!context->getExtensions().unpackSubimage)
5417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005418 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419 return false;
5420 }
5421 break;
5422
5423 case GL_PACK_ROW_LENGTH:
5424 case GL_PACK_SKIP_ROWS:
5425 case GL_PACK_SKIP_PIXELS:
5426 if (!context->getExtensions().packSubimage)
5427 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005428 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429 return false;
5430 }
5431 break;
5432 }
5433 }
5434
5435 if (param < 0)
5436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005437 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005438 return false;
5439 }
5440
5441 switch (pname)
5442 {
5443 case GL_UNPACK_ALIGNMENT:
5444 if (param != 1 && param != 2 && param != 4 && param != 8)
5445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005446 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449 break;
5450
5451 case GL_PACK_ALIGNMENT:
5452 if (param != 1 && param != 2 && param != 4 && param != 8)
5453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005454 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455 return false;
5456 }
5457 break;
5458
5459 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005460 if (!context->getExtensions().packReverseRowOrder)
5461 {
5462 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5463 }
5464 break;
5465
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 case GL_UNPACK_ROW_LENGTH:
5467 case GL_UNPACK_IMAGE_HEIGHT:
5468 case GL_UNPACK_SKIP_IMAGES:
5469 case GL_UNPACK_SKIP_ROWS:
5470 case GL_UNPACK_SKIP_PIXELS:
5471 case GL_PACK_ROW_LENGTH:
5472 case GL_PACK_SKIP_ROWS:
5473 case GL_PACK_SKIP_PIXELS:
5474 break;
5475
5476 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 return false;
5479 }
5480
5481 return true;
5482}
5483
5484bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5485{
5486 return true;
5487}
5488
5489bool ValidateReleaseShaderCompiler(ValidationContext *context)
5490{
5491 return true;
5492}
5493
Jamie Madill876429b2017-04-20 15:46:24 -04005494bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005495{
5496 return true;
5497}
5498
5499bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5500{
5501 if (width < 0 || height < 0)
5502 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005503 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504 return false;
5505 }
5506
5507 return true;
5508}
5509
5510bool ValidateShaderBinary(ValidationContext *context,
5511 GLsizei n,
5512 const GLuint *shaders,
5513 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005514 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005515 GLsizei length)
5516{
5517 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5518 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5519 shaderBinaryFormats.end())
5520 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005521 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005522 return false;
5523 }
5524
5525 return true;
5526}
5527
5528bool ValidateShaderSource(ValidationContext *context,
5529 GLuint shader,
5530 GLsizei count,
5531 const GLchar *const *string,
5532 const GLint *length)
5533{
5534 if (count < 0)
5535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005536 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537 return false;
5538 }
5539
Geoff Langfc32e8b2017-05-31 14:16:59 -04005540 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5541 // shader-related entry points
5542 if (context->getExtensions().webglCompatibility)
5543 {
5544 for (GLsizei i = 0; i < count; i++)
5545 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005546 size_t len =
5547 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005548
5549 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005550 if (!IsValidESSLShaderSourceString(string[i], len,
5551 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005552 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005553 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005554 return false;
5555 }
5556 }
5557 }
5558
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559 Shader *shaderObject = GetValidShader(context, shader);
5560 if (!shaderObject)
5561 {
5562 return false;
5563 }
5564
5565 return true;
5566}
5567
5568bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5569{
5570 if (!IsValidStencilFunc(func))
5571 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005572 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 return false;
5574 }
5575
5576 return true;
5577}
5578
5579bool ValidateStencilFuncSeparate(ValidationContext *context,
5580 GLenum face,
5581 GLenum func,
5582 GLint ref,
5583 GLuint mask)
5584{
5585 if (!IsValidStencilFace(face))
5586 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005587 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005588 return false;
5589 }
5590
5591 if (!IsValidStencilFunc(func))
5592 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005593 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005594 return false;
5595 }
5596
5597 return true;
5598}
5599
5600bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5601{
5602 return true;
5603}
5604
5605bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5606{
5607 if (!IsValidStencilFace(face))
5608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610 return false;
5611 }
5612
5613 return true;
5614}
5615
5616bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5617{
5618 if (!IsValidStencilOp(fail))
5619 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005620 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621 return false;
5622 }
5623
5624 if (!IsValidStencilOp(zfail))
5625 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005626 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005627 return false;
5628 }
5629
5630 if (!IsValidStencilOp(zpass))
5631 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005632 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005633 return false;
5634 }
5635
5636 return true;
5637}
5638
5639bool ValidateStencilOpSeparate(ValidationContext *context,
5640 GLenum face,
5641 GLenum fail,
5642 GLenum zfail,
5643 GLenum zpass)
5644{
5645 if (!IsValidStencilFace(face))
5646 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005647 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648 return false;
5649 }
5650
5651 return ValidateStencilOp(context, fail, zfail, zpass);
5652}
5653
5654bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5655{
5656 return ValidateUniform(context, GL_FLOAT, location, 1);
5657}
5658
5659bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5660{
5661 return ValidateUniform(context, GL_FLOAT, location, count);
5662}
5663
Jamie Madillbe849e42017-05-02 15:49:00 -04005664bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5665{
5666 return ValidateUniform1iv(context, location, 1, &x);
5667}
5668
Jamie Madillc1d770e2017-04-13 17:31:24 -04005669bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5670{
5671 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5672}
5673
5674bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5675{
5676 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5677}
5678
5679bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5680{
5681 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5682}
5683
5684bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5685{
5686 return ValidateUniform(context, GL_INT_VEC2, location, count);
5687}
5688
5689bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5690{
5691 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5692}
5693
5694bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5695{
5696 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5697}
5698
5699bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5700{
5701 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5702}
5703
5704bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5705{
5706 return ValidateUniform(context, GL_INT_VEC3, location, count);
5707}
5708
5709bool ValidateUniform4f(ValidationContext *context,
5710 GLint location,
5711 GLfloat x,
5712 GLfloat y,
5713 GLfloat z,
5714 GLfloat w)
5715{
5716 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5717}
5718
5719bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5720{
5721 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5722}
5723
5724bool ValidateUniform4i(ValidationContext *context,
5725 GLint location,
5726 GLint x,
5727 GLint y,
5728 GLint z,
5729 GLint w)
5730{
5731 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5732}
5733
5734bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5735{
5736 return ValidateUniform(context, GL_INT_VEC4, location, count);
5737}
5738
5739bool ValidateUniformMatrix2fv(ValidationContext *context,
5740 GLint location,
5741 GLsizei count,
5742 GLboolean transpose,
5743 const GLfloat *value)
5744{
5745 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5746}
5747
5748bool ValidateUniformMatrix3fv(ValidationContext *context,
5749 GLint location,
5750 GLsizei count,
5751 GLboolean transpose,
5752 const GLfloat *value)
5753{
5754 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5755}
5756
5757bool ValidateUniformMatrix4fv(ValidationContext *context,
5758 GLint location,
5759 GLsizei count,
5760 GLboolean transpose,
5761 const GLfloat *value)
5762{
5763 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5764}
5765
5766bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5767{
5768 Program *programObject = GetValidProgram(context, program);
5769
5770 if (!programObject)
5771 {
5772 return false;
5773 }
5774
5775 return true;
5776}
5777
Jamie Madillc1d770e2017-04-13 17:31:24 -04005778bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
5783bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
5788bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
5793bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
5798bool ValidateVertexAttrib3f(ValidationContext *context,
5799 GLuint index,
5800 GLfloat x,
5801 GLfloat y,
5802 GLfloat z)
5803{
5804 return ValidateVertexAttribIndex(context, index);
5805}
5806
5807bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5808{
5809 return ValidateVertexAttribIndex(context, index);
5810}
5811
5812bool ValidateVertexAttrib4f(ValidationContext *context,
5813 GLuint index,
5814 GLfloat x,
5815 GLfloat y,
5816 GLfloat z,
5817 GLfloat w)
5818{
5819 return ValidateVertexAttribIndex(context, index);
5820}
5821
5822bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5823{
5824 return ValidateVertexAttribIndex(context, index);
5825}
5826
5827bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5828{
5829 if (width < 0 || height < 0)
5830 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005831 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005832 return false;
5833 }
5834
5835 return true;
5836}
5837
5838bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5839{
5840 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5841}
5842
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005843bool ValidateDrawElements(ValidationContext *context,
5844 GLenum mode,
5845 GLsizei count,
5846 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005847 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005848{
5849 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5850}
5851
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005852bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005853 GLenum target,
5854 GLenum attachment,
5855 GLenum pname,
5856 GLint *params)
5857{
5858 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5859 nullptr);
5860}
5861
5862bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5863{
5864 return ValidateGetProgramivBase(context, program, pname, nullptr);
5865}
5866
5867bool ValidateCopyTexImage2D(ValidationContext *context,
5868 GLenum target,
5869 GLint level,
5870 GLenum internalformat,
5871 GLint x,
5872 GLint y,
5873 GLsizei width,
5874 GLsizei height,
5875 GLint border)
5876{
5877 if (context->getClientMajorVersion() < 3)
5878 {
5879 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5880 0, x, y, width, height, border);
5881 }
5882
5883 ASSERT(context->getClientMajorVersion() == 3);
5884 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5885 0, x, y, width, height, border);
5886}
5887
5888bool ValidateCopyTexSubImage2D(Context *context,
5889 GLenum target,
5890 GLint level,
5891 GLint xoffset,
5892 GLint yoffset,
5893 GLint x,
5894 GLint y,
5895 GLsizei width,
5896 GLsizei height)
5897{
5898 if (context->getClientMajorVersion() < 3)
5899 {
5900 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5901 yoffset, x, y, width, height, 0);
5902 }
5903
5904 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5905 yoffset, 0, x, y, width, height, 0);
5906}
5907
5908bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5909{
5910 return ValidateGenOrDelete(context, n);
5911}
5912
5913bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5914{
5915 return ValidateGenOrDelete(context, n);
5916}
5917
5918bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5919{
5920 return ValidateGenOrDelete(context, n);
5921}
5922
5923bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5924{
5925 return ValidateGenOrDelete(context, n);
5926}
5927
5928bool ValidateDisable(Context *context, GLenum cap)
5929{
5930 if (!ValidCap(context, cap, false))
5931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 return false;
5934 }
5935
5936 return true;
5937}
5938
5939bool ValidateEnable(Context *context, GLenum cap)
5940{
5941 if (!ValidCap(context, cap, false))
5942 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005943 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005944 return false;
5945 }
5946
5947 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5948 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5949 {
5950 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005951 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005952
5953 // We also output an error message to the debugger window if tracing is active, so that
5954 // developers can see the error message.
5955 ERR() << errorMessage;
5956 return false;
5957 }
5958
5959 return true;
5960}
5961
5962bool ValidateFramebufferRenderbuffer(Context *context,
5963 GLenum target,
5964 GLenum attachment,
5965 GLenum renderbuffertarget,
5966 GLuint renderbuffer)
5967{
Geoff Lange8afa902017-09-27 15:00:43 -04005968 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005969 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005970 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5971 return false;
5972 }
5973
5974 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5975 {
5976 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 return false;
5978 }
5979
5980 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5981 renderbuffertarget, renderbuffer);
5982}
5983
5984bool ValidateFramebufferTexture2D(Context *context,
5985 GLenum target,
5986 GLenum attachment,
5987 GLenum textarget,
5988 GLuint texture,
5989 GLint level)
5990{
5991 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5992 // extension
5993 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5994 level != 0)
5995 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005996 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005997 return false;
5998 }
5999
6000 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6001 {
6002 return false;
6003 }
6004
6005 if (texture != 0)
6006 {
6007 gl::Texture *tex = context->getTexture(texture);
6008 ASSERT(tex);
6009
6010 const gl::Caps &caps = context->getCaps();
6011
6012 switch (textarget)
6013 {
6014 case GL_TEXTURE_2D:
6015 {
6016 if (level > gl::log2(caps.max2DTextureSize))
6017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006018 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006019 return false;
6020 }
6021 if (tex->getTarget() != GL_TEXTURE_2D)
6022 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006023 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 return false;
6025 }
6026 }
6027 break;
6028
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006029 case GL_TEXTURE_RECTANGLE_ANGLE:
6030 {
6031 if (level != 0)
6032 {
6033 context->handleError(InvalidValue());
6034 return false;
6035 }
6036 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
6037 {
6038 context->handleError(InvalidOperation()
6039 << "Textarget must match the texture target type.");
6040 return false;
6041 }
6042 }
6043 break;
6044
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
6046 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
6047 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
6048 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
6049 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
6050 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
6051 {
6052 if (level > gl::log2(caps.maxCubeMapTextureSize))
6053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006054 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006055 return false;
6056 }
6057 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
6058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006059 context->handleError(InvalidOperation()
6060 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006061 return false;
6062 }
6063 }
6064 break;
6065
6066 case GL_TEXTURE_2D_MULTISAMPLE:
6067 {
6068 if (context->getClientVersion() < ES_3_1)
6069 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006070 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006071 return false;
6072 }
6073
6074 if (level != 0)
6075 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006076 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006077 return false;
6078 }
6079 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
6080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006081 context->handleError(InvalidOperation()
6082 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006083 return false;
6084 }
6085 }
6086 break;
6087
6088 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006089 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006090 return false;
6091 }
6092
6093 const Format &format = tex->getFormat(textarget, level);
6094 if (format.info->compressed)
6095 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006096 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 return false;
6098 }
6099 }
6100
6101 return true;
6102}
6103
6104bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6105{
6106 return ValidateGenOrDelete(context, n);
6107}
6108
6109bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6110{
6111 return ValidateGenOrDelete(context, n);
6112}
6113
6114bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6115{
6116 return ValidateGenOrDelete(context, n);
6117}
6118
6119bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6120{
6121 return ValidateGenOrDelete(context, n);
6122}
6123
6124bool ValidateGenerateMipmap(Context *context, GLenum target)
6125{
6126 if (!ValidTextureTarget(context, target))
6127 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006128 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 return false;
6130 }
6131
6132 Texture *texture = context->getTargetTexture(target);
6133
6134 if (texture == nullptr)
6135 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006136 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006137 return false;
6138 }
6139
6140 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6141
6142 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6143 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6144 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6145 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006146 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 return false;
6148 }
6149
6150 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
Geoff Lang536eca12017-09-13 11:23:35 -04006151 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6152 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6153 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006154 {
6155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6156 return false;
6157 }
6158
Geoff Lang536eca12017-09-13 11:23:35 -04006159 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6160 bool formatUnsized = !format.sized;
6161 bool formatColorRenderableAndFilterable =
6162 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6163 format.renderSupport(context->getClientVersion(), context->getExtensions());
6164 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 {
Geoff Lang536eca12017-09-13 11:23:35 -04006166 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006167 return false;
6168 }
6169
Geoff Lang536eca12017-09-13 11:23:35 -04006170 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6171 // generation
6172 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6173 {
6174 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6175 return false;
6176 }
6177
6178 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6179 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006180 bool supportsSRGBMipmapGeneration =
6181 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006182 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006183 {
Geoff Lang536eca12017-09-13 11:23:35 -04006184 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006185 return false;
6186 }
6187
6188 // Non-power of 2 ES2 check
6189 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6190 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6191 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6192 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006193 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6194 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006195 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006196 return false;
6197 }
6198
6199 // Cube completeness check
6200 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006203 return false;
6204 }
6205
6206 return true;
6207}
6208
6209bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006210 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006211 GLenum pname,
6212 GLint *params)
6213{
6214 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6215}
6216
6217bool ValidateGetRenderbufferParameteriv(Context *context,
6218 GLenum target,
6219 GLenum pname,
6220 GLint *params)
6221{
6222 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6223}
6224
6225bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6226{
6227 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6228}
6229
6230bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6231{
6232 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6233}
6234
6235bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6236{
6237 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6238}
6239
6240bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6241{
6242 return ValidateGetUniformBase(context, program, location);
6243}
6244
6245bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6246{
6247 return ValidateGetUniformBase(context, program, location);
6248}
6249
6250bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6251{
6252 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6253}
6254
6255bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6256{
6257 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6258}
6259
6260bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6261{
6262 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6263}
6264
6265bool ValidateIsEnabled(Context *context, GLenum cap)
6266{
6267 if (!ValidCap(context, cap, true))
6268 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006269 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006270 return false;
6271 }
6272
6273 return true;
6274}
6275
6276bool ValidateLinkProgram(Context *context, GLuint program)
6277{
6278 if (context->hasActiveTransformFeedback(program))
6279 {
6280 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006281 context->handleError(InvalidOperation() << "Cannot link program while program is "
6282 "associated with an active transform "
6283 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006284 return false;
6285 }
6286
6287 Program *programObject = GetValidProgram(context, program);
6288 if (!programObject)
6289 {
6290 return false;
6291 }
6292
6293 return true;
6294}
6295
Jamie Madill4928b7c2017-06-20 12:57:39 -04006296bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006297 GLint x,
6298 GLint y,
6299 GLsizei width,
6300 GLsizei height,
6301 GLenum format,
6302 GLenum type,
6303 void *pixels)
6304{
6305 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6306 nullptr, pixels);
6307}
6308
6309bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6310{
6311 return ValidateTexParameterBase(context, target, pname, -1, &param);
6312}
6313
6314bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6315{
6316 return ValidateTexParameterBase(context, target, pname, -1, params);
6317}
6318
6319bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6320{
6321 return ValidateTexParameterBase(context, target, pname, -1, &param);
6322}
6323
6324bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6325{
6326 return ValidateTexParameterBase(context, target, pname, -1, params);
6327}
6328
6329bool ValidateUseProgram(Context *context, GLuint program)
6330{
6331 if (program != 0)
6332 {
6333 Program *programObject = context->getProgram(program);
6334 if (!programObject)
6335 {
6336 // ES 3.1.0 section 7.3 page 72
6337 if (context->getShader(program))
6338 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006339 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006340 return false;
6341 }
6342 else
6343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006344 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006345 return false;
6346 }
6347 }
6348 if (!programObject->isLinked())
6349 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006351 return false;
6352 }
6353 }
6354 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6355 {
6356 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006357 context
6358 ->handleError(InvalidOperation()
6359 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006360 return false;
6361 }
6362
6363 return true;
6364}
6365
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006366bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6367{
6368 if (!context->getExtensions().fence)
6369 {
6370 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6371 return false;
6372 }
6373
6374 if (n < 0)
6375 {
6376 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6377 return false;
6378 }
6379
6380 return true;
6381}
6382
6383bool ValidateFinishFenceNV(Context *context, GLuint fence)
6384{
6385 if (!context->getExtensions().fence)
6386 {
6387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6388 return false;
6389 }
6390
6391 FenceNV *fenceObject = context->getFenceNV(fence);
6392
6393 if (fenceObject == nullptr)
6394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6396 return false;
6397 }
6398
6399 if (!fenceObject->isSet())
6400 {
6401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6402 return false;
6403 }
6404
6405 return true;
6406}
6407
6408bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6409{
6410 if (!context->getExtensions().fence)
6411 {
6412 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6413 return false;
6414 }
6415
6416 if (n < 0)
6417 {
6418 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6419 return false;
6420 }
6421
6422 return true;
6423}
6424
6425bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6426{
6427 if (!context->getExtensions().fence)
6428 {
6429 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6430 return false;
6431 }
6432
6433 FenceNV *fenceObject = context->getFenceNV(fence);
6434
6435 if (fenceObject == nullptr)
6436 {
6437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6438 return false;
6439 }
6440
6441 if (!fenceObject->isSet())
6442 {
6443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6444 return false;
6445 }
6446
6447 switch (pname)
6448 {
6449 case GL_FENCE_STATUS_NV:
6450 case GL_FENCE_CONDITION_NV:
6451 break;
6452
6453 default:
6454 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6455 return false;
6456 }
6457
6458 return true;
6459}
6460
6461bool ValidateGetGraphicsResetStatusEXT(Context *context)
6462{
6463 if (!context->getExtensions().robustness)
6464 {
6465 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6466 return false;
6467 }
6468
6469 return true;
6470}
6471
6472bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6473 GLuint shader,
6474 GLsizei bufsize,
6475 GLsizei *length,
6476 GLchar *source)
6477{
6478 if (!context->getExtensions().translatedShaderSource)
6479 {
6480 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6481 return false;
6482 }
6483
6484 if (bufsize < 0)
6485 {
6486 context->handleError(InvalidValue());
6487 return false;
6488 }
6489
6490 Shader *shaderObject = context->getShader(shader);
6491
6492 if (!shaderObject)
6493 {
6494 context->handleError(InvalidOperation());
6495 return false;
6496 }
6497
6498 return true;
6499}
6500
6501bool ValidateIsFenceNV(Context *context, GLuint fence)
6502{
6503 if (!context->getExtensions().fence)
6504 {
6505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6506 return false;
6507 }
6508
6509 return true;
6510}
6511
Jamie Madill007530e2017-12-28 14:27:04 -05006512bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6513{
6514 if (!context->getExtensions().fence)
6515 {
6516 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6517 return false;
6518 }
6519
6520 if (condition != GL_ALL_COMPLETED_NV)
6521 {
6522 context->handleError(InvalidEnum());
6523 return false;
6524 }
6525
6526 FenceNV *fenceObject = context->getFenceNV(fence);
6527
6528 if (fenceObject == nullptr)
6529 {
6530 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6531 return false;
6532 }
6533
6534 return true;
6535}
6536
6537bool ValidateTestFenceNV(Context *context, GLuint fence)
6538{
6539 if (!context->getExtensions().fence)
6540 {
6541 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6542 return false;
6543 }
6544
6545 FenceNV *fenceObject = context->getFenceNV(fence);
6546
6547 if (fenceObject == nullptr)
6548 {
6549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6550 return false;
6551 }
6552
6553 if (fenceObject->isSet() != GL_TRUE)
6554 {
6555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6556 return false;
6557 }
6558
6559 return true;
6560}
6561
6562bool ValidateTexStorage2DEXT(Context *context,
6563 GLenum target,
6564 GLsizei levels,
6565 GLenum internalformat,
6566 GLsizei width,
6567 GLsizei height)
6568{
6569 if (!context->getExtensions().textureStorage)
6570 {
6571 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6572 return false;
6573 }
6574
6575 if (context->getClientMajorVersion() < 3)
6576 {
6577 return ValidateES2TexStorageParameters(context, target, levels, internalformat, width,
6578 height);
6579 }
6580
6581 ASSERT(context->getClientMajorVersion() >= 3);
6582 return ValidateES3TexStorage2DParameters(context, target, levels, internalformat, width, height,
6583 1);
6584}
6585
6586bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6587{
6588 if (!context->getExtensions().instancedArrays)
6589 {
6590 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6591 return false;
6592 }
6593
6594 if (index >= MAX_VERTEX_ATTRIBS)
6595 {
6596 context->handleError(InvalidValue());
6597 return false;
6598 }
6599
6600 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6601 {
6602 if (index == 0 && divisor != 0)
6603 {
6604 const char *errorMessage =
6605 "The current context doesn't support setting a non-zero divisor on the "
6606 "attribute with index zero. "
6607 "Please reorder the attributes in your vertex shader so that attribute zero "
6608 "can have a zero divisor.";
6609 context->handleError(InvalidOperation() << errorMessage);
6610
6611 // We also output an error message to the debugger window if tracing is active, so
6612 // that developers can see the error message.
6613 ERR() << errorMessage;
6614 return false;
6615 }
6616 }
6617
6618 return true;
6619}
6620
6621bool ValidateTexImage3DOES(Context *context,
6622 GLenum target,
6623 GLint level,
6624 GLenum internalformat,
6625 GLsizei width,
6626 GLsizei height,
6627 GLsizei depth,
6628 GLint border,
6629 GLenum format,
6630 GLenum type,
6631 const void *pixels)
6632{
6633 UNIMPLEMENTED(); // FIXME
6634 return false;
6635}
6636
6637bool ValidatePopGroupMarkerEXT(Context *context)
6638{
6639 if (!context->getExtensions().debugMarker)
6640 {
6641 // The debug marker calls should not set error state
6642 // However, it seems reasonable to set an error state if the extension is not enabled
6643 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6644 return false;
6645 }
6646
6647 return true;
6648}
6649
Jamie Madillfa920eb2018-01-04 11:45:50 -05006650bool ValidateTexStorage1DEXT(Context *context,
6651 GLenum target,
6652 GLsizei levels,
6653 GLenum internalformat,
6654 GLsizei width)
6655{
6656 UNIMPLEMENTED();
6657 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6658 return false;
6659}
6660
6661bool ValidateTexStorage3DEXT(Context *context,
6662 GLenum target,
6663 GLsizei levels,
6664 GLenum internalformat,
6665 GLsizei width,
6666 GLsizei height,
6667 GLsizei depth)
6668{
6669 if (!context->getExtensions().textureStorage)
6670 {
6671 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6672 return false;
6673 }
6674
6675 if (context->getClientMajorVersion() < 3)
6676 {
6677 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6678 return false;
6679 }
6680
6681 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6682 depth);
6683}
6684
Jamie Madillc29968b2016-01-20 11:17:23 -05006685} // namespace gl