blob: 362b9dac2618f70c4908e84e0bc0125175e1eafe [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 Madillc29968b2016-01-20 11:17:23 -05001005} // anonymous namespace
1006
Geoff Langff5b2d52016-09-07 11:32:23 -04001007bool ValidateES2TexImageParameters(Context *context,
1008 GLenum target,
1009 GLint level,
1010 GLenum internalformat,
1011 bool isCompressed,
1012 bool isSubImage,
1013 GLint xoffset,
1014 GLint yoffset,
1015 GLsizei width,
1016 GLsizei height,
1017 GLint border,
1018 GLenum format,
1019 GLenum type,
1020 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001021 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001022{
Jamie Madill6f38f822014-06-06 17:12:20 -04001023 if (!ValidTexture2DDestinationTarget(context, target))
1024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001025 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001026 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001027 }
1028
Austin Kinross08528e12015-10-07 16:24:40 -07001029 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001030 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001031 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001032 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001033 }
1034
Brandon Jones6cad5662017-06-14 13:25:13 -07001035 if (!ValidMipLevel(context, target, level))
1036 {
1037 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1038 return false;
1039 }
1040
1041 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001042 std::numeric_limits<GLsizei>::max() - yoffset < height)
1043 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001044 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001045 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001046 }
1047
Geoff Lang6e898aa2017-06-02 11:17:26 -04001048 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1049 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1050 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1051 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1052 // case.
1053 bool nonEqualFormatsAllowed =
1054 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1055 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1056
1057 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001059 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001060 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001061 }
1062
Geoff Langaae65a42014-05-26 12:43:44 -04001063 const gl::Caps &caps = context->getCaps();
1064
Geoff Langa9be0dc2014-12-17 12:34:40 -05001065 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001066 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05001067 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1068 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001070 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001071 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001072 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001073 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001074 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
1075 {
1076 ASSERT(level == 0);
1077 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1078 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1079 {
1080 context->handleError(InvalidValue());
1081 return false;
1082 }
1083 if (isCompressed)
1084 {
1085 context->handleError(InvalidEnum()
1086 << "Rectangle texture cannot have a compressed format.");
1087 return false;
1088 }
1089 }
Geoff Lang691e58c2014-12-19 17:03:25 -05001090 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -05001091 {
1092 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001093 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001094 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001095 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001096 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001097
Geoff Langa9be0dc2014-12-17 12:34:40 -05001098 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1099 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001101 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001102 return false;
1103 }
1104 }
1105 else
1106 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001107 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001108 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001109 }
1110
He Yunchaoced53ae2016-11-29 15:00:51 +08001111 gl::Texture *texture =
1112 context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001113 if (!texture)
1114 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001116 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001117 }
1118
Geoff Langa9be0dc2014-12-17 12:34:40 -05001119 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001120 {
Geoff Langca271392017-04-05 12:30:00 -04001121 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1122 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001124 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001125 return false;
1126 }
1127
Geoff Langa9be0dc2014-12-17 12:34:40 -05001128 if (format != GL_NONE)
1129 {
Geoff Langca271392017-04-05 12:30:00 -04001130 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1131 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001132 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001134 return false;
1135 }
1136 }
1137
1138 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1139 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001141 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001142 return false;
1143 }
Geoff Langfb052642017-10-24 13:42:09 -04001144
1145 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallez336129f2017-10-17 15:55:40 -04001146 context->getGLState().getTargetBuffer(gl::BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001147 {
1148 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1149 return false;
1150 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001151 }
1152 else
1153 {
Geoff Lang69cce582015-09-17 13:20:36 -04001154 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001155 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001156 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001157 return false;
1158 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001159 }
1160
1161 // Verify zero border
1162 if (border != 0)
1163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001164 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001165 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001166 }
1167
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001168 if (isCompressed)
1169 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001170 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001171 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1172 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001173 switch (actualInternalFormat)
1174 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001175 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1176 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1177 if (!context->getExtensions().textureCompressionDXT1)
1178 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001179 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001180 return false;
1181 }
1182 break;
1183 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001184 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001185 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001186 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001187 return false;
1188 }
1189 break;
1190 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1191 if (!context->getExtensions().textureCompressionDXT5)
1192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001193 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 return false;
1195 }
1196 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001197 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1198 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1199 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1200 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1201 if (!context->getExtensions().textureCompressionS3TCsRGB)
1202 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001204 return false;
1205 }
1206 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001207 case GL_ETC1_RGB8_OES:
1208 if (!context->getExtensions().compressedETC1RGB8Texture)
1209 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001211 return false;
1212 }
Geoff Lang86f81162017-10-30 15:10:45 -04001213 if (isSubImage)
1214 {
1215 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1216 return false;
1217 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001218 break;
1219 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001220 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1221 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1222 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1223 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001224 if (!context->getExtensions().lossyETCDecode)
1225 {
Geoff Lang86f81162017-10-30 15:10:45 -04001226 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001227 return false;
1228 }
1229 break;
1230 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001232 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001233 }
Geoff Lang966c9402017-04-18 12:38:27 -04001234
1235 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001236 {
Geoff Lang966c9402017-04-18 12:38:27 -04001237 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1238 height, texture->getWidth(target, level),
1239 texture->getHeight(target, level)))
1240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001241 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001242 return false;
1243 }
1244
1245 if (format != actualInternalFormat)
1246 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001247 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001248 return false;
1249 }
1250 }
1251 else
1252 {
1253 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1254 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001255 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001256 return false;
1257 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001258 }
1259 }
1260 else
1261 {
1262 // validate <type> by itself (used as secondary key below)
1263 switch (type)
1264 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001265 case GL_UNSIGNED_BYTE:
1266 case GL_UNSIGNED_SHORT_5_6_5:
1267 case GL_UNSIGNED_SHORT_4_4_4_4:
1268 case GL_UNSIGNED_SHORT_5_5_5_1:
1269 case GL_UNSIGNED_SHORT:
1270 case GL_UNSIGNED_INT:
1271 case GL_UNSIGNED_INT_24_8_OES:
1272 case GL_HALF_FLOAT_OES:
1273 case GL_FLOAT:
1274 break;
1275 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001276 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001277 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001278 }
1279
1280 // validate <format> + <type> combinations
1281 // - invalid <format> -> sets INVALID_ENUM
1282 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1283 switch (format)
1284 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001285 case GL_ALPHA:
1286 case GL_LUMINANCE:
1287 case GL_LUMINANCE_ALPHA:
1288 switch (type)
1289 {
1290 case GL_UNSIGNED_BYTE:
1291 case GL_FLOAT:
1292 case GL_HALF_FLOAT_OES:
1293 break;
1294 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 return false;
1297 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001298 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001299 case GL_RED:
1300 case GL_RG:
1301 if (!context->getExtensions().textureRG)
1302 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001303 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001304 return false;
1305 }
1306 switch (type)
1307 {
1308 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001309 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001310 case GL_FLOAT:
1311 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001312 if (!context->getExtensions().textureFloat)
1313 {
1314 context->handleError(InvalidEnum());
1315 return false;
1316 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001317 break;
1318 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001320 return false;
1321 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001322 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001323 case GL_RGB:
1324 switch (type)
1325 {
1326 case GL_UNSIGNED_BYTE:
1327 case GL_UNSIGNED_SHORT_5_6_5:
1328 case GL_FLOAT:
1329 case GL_HALF_FLOAT_OES:
1330 break;
1331 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001333 return false;
1334 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001335 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001336 case GL_RGBA:
1337 switch (type)
1338 {
1339 case GL_UNSIGNED_BYTE:
1340 case GL_UNSIGNED_SHORT_4_4_4_4:
1341 case GL_UNSIGNED_SHORT_5_5_5_1:
1342 case GL_FLOAT:
1343 case GL_HALF_FLOAT_OES:
1344 break;
1345 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001347 return false;
1348 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001349 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001350 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001351 if (!context->getExtensions().textureFormatBGRA8888)
1352 {
1353 context->handleError(InvalidEnum());
1354 return false;
1355 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001356 switch (type)
1357 {
1358 case GL_UNSIGNED_BYTE:
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 }
1364 break;
1365 case GL_SRGB_EXT:
1366 case GL_SRGB_ALPHA_EXT:
1367 if (!context->getExtensions().sRGB)
1368 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001369 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001370 return false;
1371 }
1372 switch (type)
1373 {
1374 case GL_UNSIGNED_BYTE:
1375 break;
1376 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001377 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return false;
1379 }
1380 break;
1381 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1382 // handled below
1383 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1384 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1385 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1386 break;
1387 case GL_DEPTH_COMPONENT:
1388 switch (type)
1389 {
1390 case GL_UNSIGNED_SHORT:
1391 case GL_UNSIGNED_INT:
1392 break;
1393 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001395 return false;
1396 }
1397 break;
1398 case GL_DEPTH_STENCIL_OES:
1399 switch (type)
1400 {
1401 case GL_UNSIGNED_INT_24_8_OES:
1402 break;
1403 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001404 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001405 return false;
1406 }
1407 break;
1408 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001409 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001410 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001411 }
1412
1413 switch (format)
1414 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1416 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1417 if (context->getExtensions().textureCompressionDXT1)
1418 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001419 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 return false;
1421 }
1422 else
1423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001424 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001425 return false;
1426 }
1427 break;
1428 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1429 if (context->getExtensions().textureCompressionDXT3)
1430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001431 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 return false;
1433 }
1434 else
1435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001436 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 return false;
1438 }
1439 break;
1440 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1441 if (context->getExtensions().textureCompressionDXT5)
1442 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001443 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
1446 else
1447 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001448 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001449 return false;
1450 }
1451 break;
1452 case GL_ETC1_RGB8_OES:
1453 if (context->getExtensions().compressedETC1RGB8Texture)
1454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001455 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 else
1459 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001460 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001461 return false;
1462 }
1463 break;
1464 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001465 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1466 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1467 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1468 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001469 if (context->getExtensions().lossyETCDecode)
1470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001471 context->handleError(InvalidOperation()
1472 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001473 return false;
1474 }
1475 else
1476 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001477 context->handleError(InvalidEnum()
1478 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001479 return false;
1480 }
1481 break;
1482 case GL_DEPTH_COMPONENT:
1483 case GL_DEPTH_STENCIL_OES:
1484 if (!context->getExtensions().depthTextures)
1485 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001486 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 if (target != GL_TEXTURE_2D)
1490 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001491 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001492 return false;
1493 }
1494 // OES_depth_texture supports loading depth data and multiple levels,
1495 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001496 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001497 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001498 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1499 return false;
1500 }
1501 if (level != 0)
1502 {
1503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001504 return false;
1505 }
1506 break;
1507 default:
1508 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001509 }
1510
Geoff Lang6e898aa2017-06-02 11:17:26 -04001511 if (!isSubImage)
1512 {
1513 switch (internalformat)
1514 {
1515 case GL_RGBA32F:
1516 if (!context->getExtensions().colorBufferFloatRGBA)
1517 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001518 context->handleError(InvalidValue()
1519 << "Sized GL_RGBA32F internal format requires "
1520 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001521 return false;
1522 }
1523 if (type != GL_FLOAT)
1524 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001526 return false;
1527 }
1528 if (format != GL_RGBA)
1529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001530 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001531 return false;
1532 }
1533 break;
1534
1535 case GL_RGB32F:
1536 if (!context->getExtensions().colorBufferFloatRGB)
1537 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001538 context->handleError(InvalidValue()
1539 << "Sized GL_RGB32F internal format requires "
1540 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001541 return false;
1542 }
1543 if (type != GL_FLOAT)
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 if (format != GL_RGB)
1549 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001550 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001551 return false;
1552 }
1553 break;
1554
1555 default:
1556 break;
1557 }
1558 }
1559
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001560 if (type == GL_FLOAT)
1561 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001562 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001563 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001564 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001565 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001566 }
1567 }
1568 else if (type == GL_HALF_FLOAT_OES)
1569 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001570 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001572 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001573 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001574 }
1575 }
1576 }
1577
Geoff Langdbcced82017-06-06 15:55:54 -04001578 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1579 if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001580 imageSize))
1581 {
1582 return false;
1583 }
1584
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001585 return true;
1586}
1587
He Yunchaoced53ae2016-11-29 15:00:51 +08001588bool ValidateES2TexStorageParameters(Context *context,
1589 GLenum target,
1590 GLsizei levels,
1591 GLenum internalformat,
1592 GLsizei width,
1593 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001594{
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001595 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
1596 target != GL_TEXTURE_RECTANGLE_ANGLE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001597 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001598 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001599 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001600 }
1601
1602 if (width < 1 || height < 1 || levels < 1)
1603 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001604 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001605 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001606 }
1607
1608 if (target == GL_TEXTURE_CUBE_MAP && width != height)
1609 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001610 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001611 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001612 }
1613
1614 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1615 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001616 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001617 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001618 }
1619
Geoff Langca271392017-04-05 12:30:00 -04001620 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001621 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001622 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001623 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001624 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001625 }
1626
Geoff Langaae65a42014-05-26 12:43:44 -04001627 const gl::Caps &caps = context->getCaps();
1628
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001629 switch (target)
1630 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001631 case GL_TEXTURE_2D:
1632 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1633 static_cast<GLuint>(height) > caps.max2DTextureSize)
1634 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001635 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001636 return false;
1637 }
1638 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001639 case GL_TEXTURE_RECTANGLE_ANGLE:
1640 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1641 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1642 {
1643 context->handleError(InvalidValue());
1644 return false;
1645 }
1646 if (formatInfo.compressed)
1647 {
1648 context->handleError(InvalidEnum()
1649 << "Rectangle texture cannot have a compressed format.");
1650 return false;
1651 }
1652 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001653 case GL_TEXTURE_CUBE_MAP:
1654 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1655 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1656 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001657 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001658 return false;
1659 }
1660 break;
1661 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001662 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001663 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001664 }
1665
Geoff Langc0b9ef42014-07-02 10:02:37 -04001666 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001667 {
1668 if (!gl::isPow2(width) || !gl::isPow2(height))
1669 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001670 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001671 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001672 }
1673 }
1674
1675 switch (internalformat)
1676 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001677 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1678 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1679 if (!context->getExtensions().textureCompressionDXT1)
1680 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001681 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001682 return false;
1683 }
1684 break;
1685 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1686 if (!context->getExtensions().textureCompressionDXT3)
1687 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001688 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001689 return false;
1690 }
1691 break;
1692 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1693 if (!context->getExtensions().textureCompressionDXT5)
1694 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001695 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001696 return false;
1697 }
1698 break;
1699 case GL_ETC1_RGB8_OES:
1700 if (!context->getExtensions().compressedETC1RGB8Texture)
1701 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001702 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001703 return false;
1704 }
1705 break;
1706 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001707 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1708 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1709 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1710 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001711 if (!context->getExtensions().lossyETCDecode)
1712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001713 context->handleError(InvalidEnum()
1714 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001715 return false;
1716 }
1717 break;
1718 case GL_RGBA32F_EXT:
1719 case GL_RGB32F_EXT:
1720 case GL_ALPHA32F_EXT:
1721 case GL_LUMINANCE32F_EXT:
1722 case GL_LUMINANCE_ALPHA32F_EXT:
1723 if (!context->getExtensions().textureFloat)
1724 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001725 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001726 return false;
1727 }
1728 break;
1729 case GL_RGBA16F_EXT:
1730 case GL_RGB16F_EXT:
1731 case GL_ALPHA16F_EXT:
1732 case GL_LUMINANCE16F_EXT:
1733 case GL_LUMINANCE_ALPHA16F_EXT:
1734 if (!context->getExtensions().textureHalfFloat)
1735 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001736 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001737 return false;
1738 }
1739 break;
1740 case GL_R8_EXT:
1741 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001742 if (!context->getExtensions().textureRG)
1743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001744 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001745 return false;
1746 }
1747 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001748 case GL_R16F_EXT:
1749 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001750 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1751 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001752 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001753 return false;
1754 }
1755 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001756 case GL_R32F_EXT:
1757 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001758 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001759 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001760 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001761 return false;
1762 }
1763 break;
1764 case GL_DEPTH_COMPONENT16:
1765 case GL_DEPTH_COMPONENT32_OES:
1766 case GL_DEPTH24_STENCIL8_OES:
1767 if (!context->getExtensions().depthTextures)
1768 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001769 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001770 return false;
1771 }
1772 if (target != GL_TEXTURE_2D)
1773 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001774 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001775 return false;
1776 }
1777 // ANGLE_depth_texture only supports 1-level textures
1778 if (levels != 1)
1779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001780 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 return false;
1782 }
1783 break;
1784 default:
1785 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001786 }
1787
Geoff Lang691e58c2014-12-19 17:03:25 -05001788 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001789 if (!texture || texture->id() == 0)
1790 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001791 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001792 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001793 }
1794
Geoff Lang69cce582015-09-17 13:20:36 -04001795 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001796 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001797 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001798 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001799 }
1800
1801 return true;
1802}
1803
He Yunchaoced53ae2016-11-29 15:00:51 +08001804bool ValidateDiscardFramebufferEXT(Context *context,
1805 GLenum target,
1806 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001807 const GLenum *attachments)
1808{
Jamie Madillc29968b2016-01-20 11:17:23 -05001809 if (!context->getExtensions().discardFramebuffer)
1810 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001811 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001812 return false;
1813 }
1814
Austin Kinross08332632015-05-05 13:35:47 -07001815 bool defaultFramebuffer = false;
1816
1817 switch (target)
1818 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001819 case GL_FRAMEBUFFER:
1820 defaultFramebuffer =
1821 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1822 break;
1823 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001824 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001825 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001826 }
1827
He Yunchaoced53ae2016-11-29 15:00:51 +08001828 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1829 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001830}
1831
Austin Kinrossbc781f32015-10-26 09:27:38 -07001832bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1833{
1834 if (!context->getExtensions().vertexArrayObject)
1835 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001836 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001837 return false;
1838 }
1839
1840 return ValidateBindVertexArrayBase(context, array);
1841}
1842
Jamie Madilld7576732017-08-26 18:49:50 -04001843bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001844{
1845 if (!context->getExtensions().vertexArrayObject)
1846 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001847 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001848 return false;
1849 }
1850
Olli Etuaho41997e72016-03-10 13:38:39 +02001851 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001852}
1853
Jamie Madilld7576732017-08-26 18:49:50 -04001854bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001855{
1856 if (!context->getExtensions().vertexArrayObject)
1857 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001858 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001859 return false;
1860 }
1861
Olli Etuaho41997e72016-03-10 13:38:39 +02001862 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001863}
1864
Jamie Madilld7576732017-08-26 18:49:50 -04001865bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001866{
1867 if (!context->getExtensions().vertexArrayObject)
1868 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001869 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001870 return false;
1871 }
1872
1873 return true;
1874}
Geoff Langc5629752015-12-07 16:29:04 -05001875
1876bool ValidateProgramBinaryOES(Context *context,
1877 GLuint program,
1878 GLenum binaryFormat,
1879 const void *binary,
1880 GLint length)
1881{
1882 if (!context->getExtensions().getProgramBinary)
1883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001884 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001885 return false;
1886 }
1887
1888 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1889}
1890
1891bool ValidateGetProgramBinaryOES(Context *context,
1892 GLuint program,
1893 GLsizei bufSize,
1894 GLsizei *length,
1895 GLenum *binaryFormat,
1896 void *binary)
1897{
1898 if (!context->getExtensions().getProgramBinary)
1899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001900 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001901 return false;
1902 }
1903
1904 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1905}
Geoff Lange102fee2015-12-10 11:23:30 -05001906
Geoff Lang70d0f492015-12-10 17:45:46 -05001907static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1908{
1909 switch (source)
1910 {
1911 case GL_DEBUG_SOURCE_API:
1912 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1913 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1914 case GL_DEBUG_SOURCE_OTHER:
1915 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1916 return !mustBeThirdPartyOrApplication;
1917
1918 case GL_DEBUG_SOURCE_THIRD_PARTY:
1919 case GL_DEBUG_SOURCE_APPLICATION:
1920 return true;
1921
1922 default:
1923 return false;
1924 }
1925}
1926
1927static bool ValidDebugType(GLenum type)
1928{
1929 switch (type)
1930 {
1931 case GL_DEBUG_TYPE_ERROR:
1932 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1933 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1934 case GL_DEBUG_TYPE_PERFORMANCE:
1935 case GL_DEBUG_TYPE_PORTABILITY:
1936 case GL_DEBUG_TYPE_OTHER:
1937 case GL_DEBUG_TYPE_MARKER:
1938 case GL_DEBUG_TYPE_PUSH_GROUP:
1939 case GL_DEBUG_TYPE_POP_GROUP:
1940 return true;
1941
1942 default:
1943 return false;
1944 }
1945}
1946
1947static bool ValidDebugSeverity(GLenum severity)
1948{
1949 switch (severity)
1950 {
1951 case GL_DEBUG_SEVERITY_HIGH:
1952 case GL_DEBUG_SEVERITY_MEDIUM:
1953 case GL_DEBUG_SEVERITY_LOW:
1954 case GL_DEBUG_SEVERITY_NOTIFICATION:
1955 return true;
1956
1957 default:
1958 return false;
1959 }
1960}
1961
Geoff Lange102fee2015-12-10 11:23:30 -05001962bool ValidateDebugMessageControlKHR(Context *context,
1963 GLenum source,
1964 GLenum type,
1965 GLenum severity,
1966 GLsizei count,
1967 const GLuint *ids,
1968 GLboolean enabled)
1969{
1970 if (!context->getExtensions().debug)
1971 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001972 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001973 return false;
1974 }
1975
Geoff Lang70d0f492015-12-10 17:45:46 -05001976 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1977 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001978 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001979 return false;
1980 }
1981
1982 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1983 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001984 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001985 return false;
1986 }
1987
1988 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1989 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001990 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001991 return false;
1992 }
1993
1994 if (count > 0)
1995 {
1996 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1997 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001998 context->handleError(
1999 InvalidOperation()
2000 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002001 return false;
2002 }
2003
2004 if (severity != GL_DONT_CARE)
2005 {
Jamie Madill437fa652016-05-03 15:13:24 -04002006 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002007 InvalidOperation()
2008 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002009 return false;
2010 }
2011 }
2012
Geoff Lange102fee2015-12-10 11:23:30 -05002013 return true;
2014}
2015
2016bool ValidateDebugMessageInsertKHR(Context *context,
2017 GLenum source,
2018 GLenum type,
2019 GLuint id,
2020 GLenum severity,
2021 GLsizei length,
2022 const GLchar *buf)
2023{
2024 if (!context->getExtensions().debug)
2025 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002026 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002027 return false;
2028 }
2029
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002030 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002031 {
2032 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2033 // not generate an error.
2034 return false;
2035 }
2036
2037 if (!ValidDebugSeverity(severity))
2038 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002039 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002040 return false;
2041 }
2042
2043 if (!ValidDebugType(type))
2044 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002045 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002046 return false;
2047 }
2048
2049 if (!ValidDebugSource(source, true))
2050 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002051 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002052 return false;
2053 }
2054
2055 size_t messageLength = (length < 0) ? strlen(buf) : length;
2056 if (messageLength > context->getExtensions().maxDebugMessageLength)
2057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002058 context->handleError(InvalidValue()
2059 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002060 return false;
2061 }
2062
Geoff Lange102fee2015-12-10 11:23:30 -05002063 return true;
2064}
2065
2066bool ValidateDebugMessageCallbackKHR(Context *context,
2067 GLDEBUGPROCKHR callback,
2068 const void *userParam)
2069{
2070 if (!context->getExtensions().debug)
2071 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002072 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002073 return false;
2074 }
2075
Geoff Lange102fee2015-12-10 11:23:30 -05002076 return true;
2077}
2078
2079bool ValidateGetDebugMessageLogKHR(Context *context,
2080 GLuint count,
2081 GLsizei bufSize,
2082 GLenum *sources,
2083 GLenum *types,
2084 GLuint *ids,
2085 GLenum *severities,
2086 GLsizei *lengths,
2087 GLchar *messageLog)
2088{
2089 if (!context->getExtensions().debug)
2090 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002091 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002092 return false;
2093 }
2094
Geoff Lang70d0f492015-12-10 17:45:46 -05002095 if (bufSize < 0 && messageLog != nullptr)
2096 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002097 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002098 return false;
2099 }
2100
Geoff Lange102fee2015-12-10 11:23:30 -05002101 return true;
2102}
2103
2104bool ValidatePushDebugGroupKHR(Context *context,
2105 GLenum source,
2106 GLuint id,
2107 GLsizei length,
2108 const GLchar *message)
2109{
2110 if (!context->getExtensions().debug)
2111 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002112 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002113 return false;
2114 }
2115
Geoff Lang70d0f492015-12-10 17:45:46 -05002116 if (!ValidDebugSource(source, true))
2117 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002118 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002119 return false;
2120 }
2121
2122 size_t messageLength = (length < 0) ? strlen(message) : length;
2123 if (messageLength > context->getExtensions().maxDebugMessageLength)
2124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002125 context->handleError(InvalidValue()
2126 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002127 return false;
2128 }
2129
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002130 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002131 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002133 context
2134 ->handleError(StackOverflow()
2135 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002136 return false;
2137 }
2138
Geoff Lange102fee2015-12-10 11:23:30 -05002139 return true;
2140}
2141
2142bool ValidatePopDebugGroupKHR(Context *context)
2143{
2144 if (!context->getExtensions().debug)
2145 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002147 return false;
2148 }
2149
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002150 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002151 if (currentStackSize <= 1)
2152 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002153 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002154 return false;
2155 }
2156
2157 return true;
2158}
2159
2160static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2161{
2162 switch (identifier)
2163 {
2164 case GL_BUFFER:
2165 if (context->getBuffer(name) == nullptr)
2166 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002167 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002168 return false;
2169 }
2170 return true;
2171
2172 case GL_SHADER:
2173 if (context->getShader(name) == nullptr)
2174 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002175 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002176 return false;
2177 }
2178 return true;
2179
2180 case GL_PROGRAM:
2181 if (context->getProgram(name) == nullptr)
2182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002183 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002184 return false;
2185 }
2186 return true;
2187
2188 case GL_VERTEX_ARRAY:
2189 if (context->getVertexArray(name) == nullptr)
2190 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002191 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002192 return false;
2193 }
2194 return true;
2195
2196 case GL_QUERY:
2197 if (context->getQuery(name) == nullptr)
2198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002199 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002200 return false;
2201 }
2202 return true;
2203
2204 case GL_TRANSFORM_FEEDBACK:
2205 if (context->getTransformFeedback(name) == nullptr)
2206 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002207 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210 return true;
2211
2212 case GL_SAMPLER:
2213 if (context->getSampler(name) == nullptr)
2214 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002215 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002216 return false;
2217 }
2218 return true;
2219
2220 case GL_TEXTURE:
2221 if (context->getTexture(name) == nullptr)
2222 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002223 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002224 return false;
2225 }
2226 return true;
2227
2228 case GL_RENDERBUFFER:
2229 if (context->getRenderbuffer(name) == nullptr)
2230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002231 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002232 return false;
2233 }
2234 return true;
2235
2236 case GL_FRAMEBUFFER:
2237 if (context->getFramebuffer(name) == nullptr)
2238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002239 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002240 return false;
2241 }
2242 return true;
2243
2244 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002245 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002246 return false;
2247 }
Geoff Lange102fee2015-12-10 11:23:30 -05002248}
2249
Martin Radev9d901792016-07-15 15:58:58 +03002250static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2251{
2252 size_t labelLength = 0;
2253
2254 if (length < 0)
2255 {
2256 if (label != nullptr)
2257 {
2258 labelLength = strlen(label);
2259 }
2260 }
2261 else
2262 {
2263 labelLength = static_cast<size_t>(length);
2264 }
2265
2266 if (labelLength > context->getExtensions().maxLabelLength)
2267 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002268 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002269 return false;
2270 }
2271
2272 return true;
2273}
2274
Geoff Lange102fee2015-12-10 11:23:30 -05002275bool ValidateObjectLabelKHR(Context *context,
2276 GLenum identifier,
2277 GLuint name,
2278 GLsizei length,
2279 const GLchar *label)
2280{
2281 if (!context->getExtensions().debug)
2282 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002283 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002284 return false;
2285 }
2286
Geoff Lang70d0f492015-12-10 17:45:46 -05002287 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2288 {
2289 return false;
2290 }
2291
Martin Radev9d901792016-07-15 15:58:58 +03002292 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 return false;
2295 }
2296
Geoff Lange102fee2015-12-10 11:23:30 -05002297 return true;
2298}
2299
2300bool ValidateGetObjectLabelKHR(Context *context,
2301 GLenum identifier,
2302 GLuint name,
2303 GLsizei bufSize,
2304 GLsizei *length,
2305 GLchar *label)
2306{
2307 if (!context->getExtensions().debug)
2308 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002310 return false;
2311 }
2312
Geoff Lang70d0f492015-12-10 17:45:46 -05002313 if (bufSize < 0)
2314 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002315 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002316 return false;
2317 }
2318
2319 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2320 {
2321 return false;
2322 }
2323
Martin Radev9d901792016-07-15 15:58:58 +03002324 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002325}
2326
2327static bool ValidateObjectPtrName(Context *context, const void *ptr)
2328{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002329 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002330 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002331 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002332 return false;
2333 }
2334
Geoff Lange102fee2015-12-10 11:23:30 -05002335 return true;
2336}
2337
2338bool ValidateObjectPtrLabelKHR(Context *context,
2339 const void *ptr,
2340 GLsizei length,
2341 const GLchar *label)
2342{
2343 if (!context->getExtensions().debug)
2344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002346 return false;
2347 }
2348
Geoff Lang70d0f492015-12-10 17:45:46 -05002349 if (!ValidateObjectPtrName(context, ptr))
2350 {
2351 return false;
2352 }
2353
Martin Radev9d901792016-07-15 15:58:58 +03002354 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002355 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 return false;
2357 }
2358
Geoff Lange102fee2015-12-10 11:23:30 -05002359 return true;
2360}
2361
2362bool ValidateGetObjectPtrLabelKHR(Context *context,
2363 const void *ptr,
2364 GLsizei bufSize,
2365 GLsizei *length,
2366 GLchar *label)
2367{
2368 if (!context->getExtensions().debug)
2369 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002370 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002371 return false;
2372 }
2373
Geoff Lang70d0f492015-12-10 17:45:46 -05002374 if (bufSize < 0)
2375 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002376 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002377 return false;
2378 }
2379
2380 if (!ValidateObjectPtrName(context, ptr))
2381 {
2382 return false;
2383 }
2384
Martin Radev9d901792016-07-15 15:58:58 +03002385 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002386}
2387
2388bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2389{
2390 if (!context->getExtensions().debug)
2391 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002393 return false;
2394 }
2395
Geoff Lang70d0f492015-12-10 17:45:46 -05002396 // TODO: represent this in Context::getQueryParameterInfo.
2397 switch (pname)
2398 {
2399 case GL_DEBUG_CALLBACK_FUNCTION:
2400 case GL_DEBUG_CALLBACK_USER_PARAM:
2401 break;
2402
2403 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002404 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002405 return false;
2406 }
2407
Geoff Lange102fee2015-12-10 11:23:30 -05002408 return true;
2409}
Jamie Madillc29968b2016-01-20 11:17:23 -05002410
2411bool ValidateBlitFramebufferANGLE(Context *context,
2412 GLint srcX0,
2413 GLint srcY0,
2414 GLint srcX1,
2415 GLint srcY1,
2416 GLint dstX0,
2417 GLint dstY0,
2418 GLint dstX1,
2419 GLint dstY1,
2420 GLbitfield mask,
2421 GLenum filter)
2422{
2423 if (!context->getExtensions().framebufferBlit)
2424 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002425 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002426 return false;
2427 }
2428
2429 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2430 {
2431 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002432 context->handleError(InvalidOperation() << "Scaling and flipping in "
2433 "BlitFramebufferANGLE not supported by this "
2434 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002435 return false;
2436 }
2437
2438 if (filter == GL_LINEAR)
2439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002440 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002441 return false;
2442 }
2443
Jamie Madill51f40ec2016-06-15 14:06:00 -04002444 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2445 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002446
2447 if (mask & GL_COLOR_BUFFER_BIT)
2448 {
2449 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2450 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2451
2452 if (readColorAttachment && drawColorAttachment)
2453 {
2454 if (!(readColorAttachment->type() == GL_TEXTURE &&
2455 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2456 readColorAttachment->type() != GL_RENDERBUFFER &&
2457 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002459 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002460 return false;
2461 }
2462
Geoff Langa15472a2015-08-11 11:48:03 -04002463 for (size_t drawbufferIdx = 0;
2464 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002465 {
Geoff Langa15472a2015-08-11 11:48:03 -04002466 const FramebufferAttachment *attachment =
2467 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2468 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002469 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002470 if (!(attachment->type() == GL_TEXTURE &&
2471 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2472 attachment->type() != GL_RENDERBUFFER &&
2473 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2474 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002475 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002476 return false;
2477 }
2478
2479 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002480 if (!Format::EquivalentForBlit(attachment->getFormat(),
2481 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002482 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002483 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 return false;
2485 }
2486 }
2487 }
2488
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002489 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002490 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2491 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2492 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002493 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002494 return false;
2495 }
2496 }
2497 }
2498
2499 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2500 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2501 for (size_t i = 0; i < 2; i++)
2502 {
2503 if (mask & masks[i])
2504 {
2505 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002506 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002507 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002508 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002509
2510 if (readBuffer && drawBuffer)
2511 {
2512 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2513 dstX0, dstY0, dstX1, dstY1))
2514 {
2515 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002516 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2517 "stencil blits are supported by "
2518 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002519 return false;
2520 }
2521
2522 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2523 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002524 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002525 return false;
2526 }
2527 }
2528 }
2529 }
2530
2531 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2532 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002533}
Jamie Madillc29968b2016-01-20 11:17:23 -05002534
2535bool ValidateClear(ValidationContext *context, GLbitfield mask)
2536{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002537 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002538 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002539 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002540 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002541 return false;
2542 }
2543
2544 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2545 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002546 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002547 return false;
2548 }
2549
Geoff Lang76e65652017-03-27 14:58:02 -04002550 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2551 {
2552 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2553 GL_SIGNED_NORMALIZED};
2554
Corentin Wallez59c41592017-07-11 13:19:54 -04002555 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002556 drawBufferIdx++)
2557 {
2558 if (!ValidateWebGLFramebufferAttachmentClearType(
2559 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2560 {
2561 return false;
2562 }
2563 }
2564 }
2565
Jamie Madillc29968b2016-01-20 11:17:23 -05002566 return true;
2567}
2568
2569bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2570{
2571 if (!context->getExtensions().drawBuffers)
2572 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002573 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002574 return false;
2575 }
2576
2577 return ValidateDrawBuffersBase(context, n, bufs);
2578}
2579
Jamie Madill73a84962016-02-12 09:27:23 -05002580bool ValidateTexImage2D(Context *context,
2581 GLenum target,
2582 GLint level,
2583 GLint internalformat,
2584 GLsizei width,
2585 GLsizei height,
2586 GLint border,
2587 GLenum format,
2588 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002589 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002590{
Martin Radev1be913c2016-07-11 17:59:16 +03002591 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002592 {
2593 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002594 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002595 }
2596
Martin Radev1be913c2016-07-11 17:59:16 +03002597 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002598 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002599 0, 0, width, height, 1, border, format, type, -1,
2600 pixels);
2601}
2602
2603bool ValidateTexImage2DRobust(Context *context,
2604 GLenum target,
2605 GLint level,
2606 GLint internalformat,
2607 GLsizei width,
2608 GLsizei height,
2609 GLint border,
2610 GLenum format,
2611 GLenum type,
2612 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002613 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002614{
2615 if (!ValidateRobustEntryPoint(context, bufSize))
2616 {
2617 return false;
2618 }
2619
2620 if (context->getClientMajorVersion() < 3)
2621 {
2622 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2623 0, 0, width, height, border, format, type, bufSize,
2624 pixels);
2625 }
2626
2627 ASSERT(context->getClientMajorVersion() >= 3);
2628 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2629 0, 0, width, height, 1, border, format, type, bufSize,
2630 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002631}
2632
2633bool ValidateTexSubImage2D(Context *context,
2634 GLenum target,
2635 GLint level,
2636 GLint xoffset,
2637 GLint yoffset,
2638 GLsizei width,
2639 GLsizei height,
2640 GLenum format,
2641 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002642 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002643{
2644
Martin Radev1be913c2016-07-11 17:59:16 +03002645 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002646 {
2647 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002648 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002649 }
2650
Martin Radev1be913c2016-07-11 17:59:16 +03002651 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002652 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002653 yoffset, 0, width, height, 1, 0, format, type, -1,
2654 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002655}
2656
Geoff Langc52f6f12016-10-14 10:18:00 -04002657bool ValidateTexSubImage2DRobustANGLE(Context *context,
2658 GLenum target,
2659 GLint level,
2660 GLint xoffset,
2661 GLint yoffset,
2662 GLsizei width,
2663 GLsizei height,
2664 GLenum format,
2665 GLenum type,
2666 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002667 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002668{
2669 if (!ValidateRobustEntryPoint(context, bufSize))
2670 {
2671 return false;
2672 }
2673
2674 if (context->getClientMajorVersion() < 3)
2675 {
2676 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2677 yoffset, width, height, 0, format, type, bufSize,
2678 pixels);
2679 }
2680
2681 ASSERT(context->getClientMajorVersion() >= 3);
2682 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2683 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2684 pixels);
2685}
2686
Jamie Madill73a84962016-02-12 09:27:23 -05002687bool ValidateCompressedTexImage2D(Context *context,
2688 GLenum target,
2689 GLint level,
2690 GLenum internalformat,
2691 GLsizei width,
2692 GLsizei height,
2693 GLint border,
2694 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002695 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002696{
Martin Radev1be913c2016-07-11 17:59:16 +03002697 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002698 {
2699 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002700 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002701 {
2702 return false;
2703 }
2704 }
2705 else
2706 {
Martin Radev1be913c2016-07-11 17:59:16 +03002707 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002708 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002709 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002710 data))
2711 {
2712 return false;
2713 }
2714 }
2715
Geoff Langca271392017-04-05 12:30:00 -04002716 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002717 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002718 if (blockSizeOrErr.isError())
2719 {
2720 context->handleError(blockSizeOrErr.getError());
2721 return false;
2722 }
2723
2724 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002725 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002726 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002727 return false;
2728 }
2729
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002730 if (target == GL_TEXTURE_RECTANGLE_ANGLE)
2731 {
2732 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2733 return false;
2734 }
2735
Jamie Madill73a84962016-02-12 09:27:23 -05002736 return true;
2737}
2738
Corentin Wallezb2931602017-04-11 15:58:57 -04002739bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
2740 GLenum target,
2741 GLint level,
2742 GLenum internalformat,
2743 GLsizei width,
2744 GLsizei height,
2745 GLint border,
2746 GLsizei imageSize,
2747 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002748 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002749{
2750 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2751 {
2752 return false;
2753 }
2754
2755 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2756 border, imageSize, data);
2757}
2758bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
2759 GLenum target,
2760 GLint level,
2761 GLint xoffset,
2762 GLint yoffset,
2763 GLsizei width,
2764 GLsizei height,
2765 GLenum format,
2766 GLsizei imageSize,
2767 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002768 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002769{
2770 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2771 {
2772 return false;
2773 }
2774
2775 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2776 format, imageSize, data);
2777}
2778
Jamie Madill73a84962016-02-12 09:27:23 -05002779bool ValidateCompressedTexSubImage2D(Context *context,
2780 GLenum target,
2781 GLint level,
2782 GLint xoffset,
2783 GLint yoffset,
2784 GLsizei width,
2785 GLsizei height,
2786 GLenum format,
2787 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002788 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002789{
Martin Radev1be913c2016-07-11 17:59:16 +03002790 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002791 {
2792 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002793 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002794 {
2795 return false;
2796 }
2797 }
2798 else
2799 {
Martin Radev1be913c2016-07-11 17:59:16 +03002800 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002801 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002802 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002803 data))
2804 {
2805 return false;
2806 }
2807 }
2808
Geoff Langca271392017-04-05 12:30:00 -04002809 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002810 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002811 if (blockSizeOrErr.isError())
2812 {
2813 context->handleError(blockSizeOrErr.getError());
2814 return false;
2815 }
2816
2817 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002818 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002819 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002820 return false;
2821 }
2822
2823 return true;
2824}
2825
Corentin Wallez336129f2017-10-17 15:55:40 -04002826bool ValidateGetBufferPointervOES(Context *context,
2827 BufferBinding target,
2828 GLenum pname,
2829 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002830{
Geoff Lang496c02d2016-10-20 11:38:11 -07002831 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002832}
2833
Corentin Wallez336129f2017-10-17 15:55:40 -04002834bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002835{
2836 if (!context->getExtensions().mapBuffer)
2837 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002838 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002839 return false;
2840 }
2841
Corentin Walleze4477002017-12-01 14:39:58 -05002842 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002843 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002844 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002845 return false;
2846 }
2847
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002848 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002849
2850 if (buffer == nullptr)
2851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002852 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002853 return false;
2854 }
2855
2856 if (access != GL_WRITE_ONLY_OES)
2857 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002858 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002859 return false;
2860 }
2861
2862 if (buffer->isMapped())
2863 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002864 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002865 return false;
2866 }
2867
Geoff Lang79f71042017-08-14 16:43:43 -04002868 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002869}
2870
Corentin Wallez336129f2017-10-17 15:55:40 -04002871bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002872{
2873 if (!context->getExtensions().mapBuffer)
2874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002875 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002876 return false;
2877 }
2878
2879 return ValidateUnmapBufferBase(context, target);
2880}
2881
2882bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002883 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002884 GLintptr offset,
2885 GLsizeiptr length,
2886 GLbitfield access)
2887{
2888 if (!context->getExtensions().mapBufferRange)
2889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002890 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002891 return false;
2892 }
2893
2894 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2895}
2896
Corentin Wallez336129f2017-10-17 15:55:40 -04002897bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002898{
2899 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2900 ASSERT(buffer != nullptr);
2901
2902 // Check if this buffer is currently being used as a transform feedback output buffer
2903 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2904 if (transformFeedback != nullptr && transformFeedback->isActive())
2905 {
2906 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2907 {
2908 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2909 if (transformFeedbackBuffer.get() == buffer)
2910 {
2911 context->handleError(InvalidOperation()
2912 << "Buffer is currently bound for transform feedback.");
2913 return false;
2914 }
2915 }
2916 }
2917
2918 return true;
2919}
2920
Olli Etuaho4f667482016-03-30 15:56:35 +03002921bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002922 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002923 GLintptr offset,
2924 GLsizeiptr length)
2925{
2926 if (!context->getExtensions().mapBufferRange)
2927 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002928 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002929 return false;
2930 }
2931
2932 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2933}
2934
Ian Ewell54f87462016-03-10 13:47:21 -05002935bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
2936{
2937 Texture *textureObject = context->getTexture(texture);
2938 if (textureObject && textureObject->getTarget() != target && texture != 0)
2939 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002940 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002941 return false;
2942 }
2943
Geoff Langf41a7152016-09-19 15:11:17 -04002944 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2945 !context->isTextureGenerated(texture))
2946 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002947 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002948 return false;
2949 }
2950
Ian Ewell54f87462016-03-10 13:47:21 -05002951 switch (target)
2952 {
2953 case GL_TEXTURE_2D:
2954 case GL_TEXTURE_CUBE_MAP:
2955 break;
2956
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002957 case GL_TEXTURE_RECTANGLE_ANGLE:
2958 if (!context->getExtensions().textureRectangle)
2959 {
2960 context->handleError(InvalidEnum()
2961 << "Context does not support GL_ANGLE_texture_rectangle");
2962 return false;
2963 }
2964 break;
2965
Ian Ewell54f87462016-03-10 13:47:21 -05002966 case GL_TEXTURE_3D:
2967 case GL_TEXTURE_2D_ARRAY:
Martin Radev1be913c2016-07-11 17:59:16 +03002968 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002969 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002970 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002971 return false;
2972 }
2973 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002974
2975 case GL_TEXTURE_2D_MULTISAMPLE:
2976 if (context->getClientVersion() < Version(3, 1))
2977 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002978 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002979 return false;
2980 }
Geoff Lang3b573612016-10-31 14:08:10 -04002981 break;
2982
Ian Ewell54f87462016-03-10 13:47:21 -05002983 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002984 if (!context->getExtensions().eglImageExternal &&
2985 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002986 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002987 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002988 return false;
2989 }
2990 break;
2991 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002992 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002993 return false;
2994 }
2995
2996 return true;
2997}
2998
Geoff Langd8605522016-04-13 10:19:12 -04002999bool ValidateBindUniformLocationCHROMIUM(Context *context,
3000 GLuint program,
3001 GLint location,
3002 const GLchar *name)
3003{
3004 if (!context->getExtensions().bindUniformLocation)
3005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003006 context->handleError(InvalidOperation()
3007 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003008 return false;
3009 }
3010
3011 Program *programObject = GetValidProgram(context, program);
3012 if (!programObject)
3013 {
3014 return false;
3015 }
3016
3017 if (location < 0)
3018 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003019 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003020 return false;
3021 }
3022
3023 const Caps &caps = context->getCaps();
3024 if (static_cast<size_t>(location) >=
3025 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3026 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003027 context->handleError(InvalidValue() << "Location must be less than "
3028 "(MAX_VERTEX_UNIFORM_VECTORS + "
3029 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003030 return false;
3031 }
3032
Geoff Langfc32e8b2017-05-31 14:16:59 -04003033 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3034 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003035 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003036 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003037 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003038 return false;
3039 }
3040
Geoff Langd8605522016-04-13 10:19:12 -04003041 if (strncmp(name, "gl_", 3) == 0)
3042 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003043 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003044 return false;
3045 }
3046
3047 return true;
3048}
3049
Jamie Madille2e406c2016-06-02 13:04:10 -04003050bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003051{
3052 if (!context->getExtensions().framebufferMixedSamples)
3053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003054 context->handleError(InvalidOperation()
3055 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003056 return false;
3057 }
3058 switch (components)
3059 {
3060 case GL_RGB:
3061 case GL_RGBA:
3062 case GL_ALPHA:
3063 case GL_NONE:
3064 break;
3065 default:
3066 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003067 InvalidEnum()
3068 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003069 return false;
3070 }
3071
3072 return true;
3073}
3074
Sami Väisänene45e53b2016-05-25 10:36:04 +03003075// CHROMIUM_path_rendering
3076
3077bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
3078{
3079 if (!context->getExtensions().pathRendering)
3080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003081 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003082 return false;
3083 }
3084 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3085 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003086 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003087 return false;
3088 }
3089 if (matrix == nullptr)
3090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003091 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092 return false;
3093 }
3094 return true;
3095}
3096
3097bool ValidateMatrixMode(Context *context, GLenum matrixMode)
3098{
3099 if (!context->getExtensions().pathRendering)
3100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003101 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003102 return false;
3103 }
3104 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3105 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003106 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003107 return false;
3108 }
3109 return true;
3110}
3111
3112bool ValidateGenPaths(Context *context, GLsizei range)
3113{
3114 if (!context->getExtensions().pathRendering)
3115 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003116 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117 return false;
3118 }
3119
3120 // range = 0 is undefined in NV_path_rendering.
3121 // we add stricter semantic check here and require a non zero positive range.
3122 if (range <= 0)
3123 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003124 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003125 return false;
3126 }
3127
3128 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003130 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003131 return false;
3132 }
3133
3134 return true;
3135}
3136
3137bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
3138{
3139 if (!context->getExtensions().pathRendering)
3140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003141 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003142 return false;
3143 }
3144
3145 // range = 0 is undefined in NV_path_rendering.
3146 // we add stricter semantic check here and require a non zero positive range.
3147 if (range <= 0)
3148 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003149 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003150 return false;
3151 }
3152
3153 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3154 checkedRange += range;
3155
3156 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3157 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003158 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003159 return false;
3160 }
3161 return true;
3162}
3163
3164bool ValidatePathCommands(Context *context,
3165 GLuint path,
3166 GLsizei numCommands,
3167 const GLubyte *commands,
3168 GLsizei numCoords,
3169 GLenum coordType,
3170 const void *coords)
3171{
3172 if (!context->getExtensions().pathRendering)
3173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003174 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003175 return false;
3176 }
3177 if (!context->hasPath(path))
3178 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003180 return false;
3181 }
3182
3183 if (numCommands < 0)
3184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003185 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003186 return false;
3187 }
3188 else if (numCommands > 0)
3189 {
3190 if (!commands)
3191 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003192 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003193 return false;
3194 }
3195 }
3196
3197 if (numCoords < 0)
3198 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003199 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003200 return false;
3201 }
3202 else if (numCoords > 0)
3203 {
3204 if (!coords)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209 }
3210
3211 std::uint32_t coordTypeSize = 0;
3212 switch (coordType)
3213 {
3214 case GL_BYTE:
3215 coordTypeSize = sizeof(GLbyte);
3216 break;
3217
3218 case GL_UNSIGNED_BYTE:
3219 coordTypeSize = sizeof(GLubyte);
3220 break;
3221
3222 case GL_SHORT:
3223 coordTypeSize = sizeof(GLshort);
3224 break;
3225
3226 case GL_UNSIGNED_SHORT:
3227 coordTypeSize = sizeof(GLushort);
3228 break;
3229
3230 case GL_FLOAT:
3231 coordTypeSize = sizeof(GLfloat);
3232 break;
3233
3234 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003235 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003236 return false;
3237 }
3238
3239 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3240 checkedSize += (coordTypeSize * numCoords);
3241 if (!checkedSize.IsValid())
3242 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003243 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003244 return false;
3245 }
3246
3247 // early return skips command data validation when it doesn't exist.
3248 if (!commands)
3249 return true;
3250
3251 GLsizei expectedNumCoords = 0;
3252 for (GLsizei i = 0; i < numCommands; ++i)
3253 {
3254 switch (commands[i])
3255 {
3256 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3257 break;
3258 case GL_MOVE_TO_CHROMIUM:
3259 case GL_LINE_TO_CHROMIUM:
3260 expectedNumCoords += 2;
3261 break;
3262 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3263 expectedNumCoords += 4;
3264 break;
3265 case GL_CUBIC_CURVE_TO_CHROMIUM:
3266 expectedNumCoords += 6;
3267 break;
3268 case GL_CONIC_CURVE_TO_CHROMIUM:
3269 expectedNumCoords += 5;
3270 break;
3271 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003272 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003273 return false;
3274 }
3275 }
3276 if (expectedNumCoords != numCoords)
3277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003278 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003279 return false;
3280 }
3281
3282 return true;
3283}
3284
3285bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
3286{
3287 if (!context->getExtensions().pathRendering)
3288 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003289 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003290 return false;
3291 }
3292 if (!context->hasPath(path))
3293 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003295 return false;
3296 }
3297
3298 switch (pname)
3299 {
3300 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3301 if (value < 0.0f)
3302 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003303 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
3306 break;
3307 case GL_PATH_END_CAPS_CHROMIUM:
3308 switch (static_cast<GLenum>(value))
3309 {
3310 case GL_FLAT_CHROMIUM:
3311 case GL_SQUARE_CHROMIUM:
3312 case GL_ROUND_CHROMIUM:
3313 break;
3314 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003315 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003316 return false;
3317 }
3318 break;
3319 case GL_PATH_JOIN_STYLE_CHROMIUM:
3320 switch (static_cast<GLenum>(value))
3321 {
3322 case GL_MITER_REVERT_CHROMIUM:
3323 case GL_BEVEL_CHROMIUM:
3324 case GL_ROUND_CHROMIUM:
3325 break;
3326 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003327 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003328 return false;
3329 }
3330 case GL_PATH_MITER_LIMIT_CHROMIUM:
3331 if (value < 0.0f)
3332 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003333 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003334 return false;
3335 }
3336 break;
3337
3338 case GL_PATH_STROKE_BOUND_CHROMIUM:
3339 // no errors, only clamping.
3340 break;
3341
3342 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003343 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003344 return false;
3345 }
3346 return true;
3347}
3348
3349bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
3350{
3351 if (!context->getExtensions().pathRendering)
3352 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003353 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003354 return false;
3355 }
3356
3357 if (!context->hasPath(path))
3358 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003359 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360 return false;
3361 }
3362 if (!value)
3363 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003364 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003365 return false;
3366 }
3367
3368 switch (pname)
3369 {
3370 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3371 case GL_PATH_END_CAPS_CHROMIUM:
3372 case GL_PATH_JOIN_STYLE_CHROMIUM:
3373 case GL_PATH_MITER_LIMIT_CHROMIUM:
3374 case GL_PATH_STROKE_BOUND_CHROMIUM:
3375 break;
3376
3377 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381
3382 return true;
3383}
3384
3385bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
3386{
3387 if (!context->getExtensions().pathRendering)
3388 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003389 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390 return false;
3391 }
3392
3393 switch (func)
3394 {
3395 case GL_NEVER:
3396 case GL_ALWAYS:
3397 case GL_LESS:
3398 case GL_LEQUAL:
3399 case GL_EQUAL:
3400 case GL_GEQUAL:
3401 case GL_GREATER:
3402 case GL_NOTEQUAL:
3403 break;
3404 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003405 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003406 return false;
3407 }
3408
3409 return true;
3410}
3411
3412// Note that the spec specifies that for the path drawing commands
3413// if the path object is not an existing path object the command
3414// does nothing and no error is generated.
3415// However if the path object exists but has not been specified any
3416// commands then an error is generated.
3417
3418bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
3419{
3420 if (!context->getExtensions().pathRendering)
3421 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003422 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423 return false;
3424 }
3425 if (context->hasPath(path) && !context->hasPathData(path))
3426 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003427 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003428 return false;
3429 }
3430
3431 switch (fillMode)
3432 {
3433 case GL_COUNT_UP_CHROMIUM:
3434 case GL_COUNT_DOWN_CHROMIUM:
3435 break;
3436 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003437 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003438 return false;
3439 }
3440
3441 if (!isPow2(mask + 1))
3442 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003443 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003444 return false;
3445 }
3446
3447 return true;
3448}
3449
3450bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
3451{
3452 if (!context->getExtensions().pathRendering)
3453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003454 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003455 return false;
3456 }
3457 if (context->hasPath(path) && !context->hasPathData(path))
3458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003459 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 return false;
3461 }
3462
3463 return true;
3464}
3465
3466bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode)
3467{
3468 if (!context->getExtensions().pathRendering)
3469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003470 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003471 return false;
3472 }
3473 if (context->hasPath(path) && !context->hasPathData(path))
3474 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003475 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003476 return false;
3477 }
3478
3479 switch (coverMode)
3480 {
3481 case GL_CONVEX_HULL_CHROMIUM:
3482 case GL_BOUNDING_BOX_CHROMIUM:
3483 break;
3484 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003485 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003486 return false;
3487 }
3488 return true;
3489}
3490
3491bool ValidateStencilThenCoverFillPath(Context *context,
3492 GLuint path,
3493 GLenum fillMode,
3494 GLuint mask,
3495 GLenum coverMode)
3496{
3497 return ValidateStencilFillPath(context, path, fillMode, mask) &&
3498 ValidateCoverPath(context, path, coverMode);
3499}
3500
3501bool ValidateStencilThenCoverStrokePath(Context *context,
3502 GLuint path,
3503 GLint reference,
3504 GLuint mask,
3505 GLenum coverMode)
3506{
3507 return ValidateStencilStrokePath(context, path, reference, mask) &&
3508 ValidateCoverPath(context, path, coverMode);
3509}
3510
3511bool ValidateIsPath(Context *context)
3512{
3513 if (!context->getExtensions().pathRendering)
3514 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003515 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516 return false;
3517 }
3518 return true;
3519}
3520
Sami Väisänend59ca052016-06-21 16:10:00 +03003521bool ValidateCoverFillPathInstanced(Context *context,
3522 GLsizei numPaths,
3523 GLenum pathNameType,
3524 const void *paths,
3525 GLuint pathBase,
3526 GLenum coverMode,
3527 GLenum transformType,
3528 const GLfloat *transformValues)
3529{
3530 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3531 transformType, transformValues))
3532 return false;
3533
3534 switch (coverMode)
3535 {
3536 case GL_CONVEX_HULL_CHROMIUM:
3537 case GL_BOUNDING_BOX_CHROMIUM:
3538 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3539 break;
3540 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003542 return false;
3543 }
3544
3545 return true;
3546}
3547
3548bool ValidateCoverStrokePathInstanced(Context *context,
3549 GLsizei numPaths,
3550 GLenum pathNameType,
3551 const void *paths,
3552 GLuint pathBase,
3553 GLenum coverMode,
3554 GLenum transformType,
3555 const GLfloat *transformValues)
3556{
3557 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3558 transformType, transformValues))
3559 return false;
3560
3561 switch (coverMode)
3562 {
3563 case GL_CONVEX_HULL_CHROMIUM:
3564 case GL_BOUNDING_BOX_CHROMIUM:
3565 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3566 break;
3567 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003568 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003569 return false;
3570 }
3571
3572 return true;
3573}
3574
3575bool ValidateStencilFillPathInstanced(Context *context,
3576 GLsizei numPaths,
3577 GLenum pathNameType,
3578 const void *paths,
3579 GLuint pathBase,
3580 GLenum fillMode,
3581 GLuint mask,
3582 GLenum transformType,
3583 const GLfloat *transformValues)
3584{
3585
3586 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3587 transformType, transformValues))
3588 return false;
3589
3590 switch (fillMode)
3591 {
3592 case GL_COUNT_UP_CHROMIUM:
3593 case GL_COUNT_DOWN_CHROMIUM:
3594 break;
3595 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003597 return false;
3598 }
3599 if (!isPow2(mask + 1))
3600 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003601 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003602 return false;
3603 }
3604 return true;
3605}
3606
3607bool ValidateStencilStrokePathInstanced(Context *context,
3608 GLsizei numPaths,
3609 GLenum pathNameType,
3610 const void *paths,
3611 GLuint pathBase,
3612 GLint reference,
3613 GLuint mask,
3614 GLenum transformType,
3615 const GLfloat *transformValues)
3616{
3617 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3618 transformType, transformValues))
3619 return false;
3620
3621 // no more validation here.
3622
3623 return true;
3624}
3625
3626bool ValidateStencilThenCoverFillPathInstanced(Context *context,
3627 GLsizei numPaths,
3628 GLenum pathNameType,
3629 const void *paths,
3630 GLuint pathBase,
3631 GLenum fillMode,
3632 GLuint mask,
3633 GLenum coverMode,
3634 GLenum transformType,
3635 const GLfloat *transformValues)
3636{
3637 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3638 transformType, transformValues))
3639 return false;
3640
3641 switch (coverMode)
3642 {
3643 case GL_CONVEX_HULL_CHROMIUM:
3644 case GL_BOUNDING_BOX_CHROMIUM:
3645 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3646 break;
3647 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003648 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003649 return false;
3650 }
3651
3652 switch (fillMode)
3653 {
3654 case GL_COUNT_UP_CHROMIUM:
3655 case GL_COUNT_DOWN_CHROMIUM:
3656 break;
3657 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003658 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003659 return false;
3660 }
3661 if (!isPow2(mask + 1))
3662 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003663 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003664 return false;
3665 }
3666
3667 return true;
3668}
3669
3670bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
3671 GLsizei numPaths,
3672 GLenum pathNameType,
3673 const void *paths,
3674 GLuint pathBase,
3675 GLint reference,
3676 GLuint mask,
3677 GLenum coverMode,
3678 GLenum transformType,
3679 const GLfloat *transformValues)
3680{
3681 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3682 transformType, transformValues))
3683 return false;
3684
3685 switch (coverMode)
3686 {
3687 case GL_CONVEX_HULL_CHROMIUM:
3688 case GL_BOUNDING_BOX_CHROMIUM:
3689 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3690 break;
3691 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003692 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003693 return false;
3694 }
3695
3696 return true;
3697}
3698
Sami Väisänen46eaa942016-06-29 10:26:37 +03003699bool ValidateBindFragmentInputLocation(Context *context,
3700 GLuint program,
3701 GLint location,
3702 const GLchar *name)
3703{
3704 if (!context->getExtensions().pathRendering)
3705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003706 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003707 return false;
3708 }
3709
3710 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3711 if (location >= MaxLocation)
3712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003713 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003714 return false;
3715 }
3716
3717 const auto *programObject = context->getProgram(program);
3718 if (!programObject)
3719 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003720 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003721 return false;
3722 }
3723
3724 if (!name)
3725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003726 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003727 return false;
3728 }
3729
3730 if (angle::BeginsWith(name, "gl_"))
3731 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003732 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003733 return false;
3734 }
3735
3736 return true;
3737}
3738
3739bool ValidateProgramPathFragmentInputGen(Context *context,
3740 GLuint program,
3741 GLint location,
3742 GLenum genMode,
3743 GLint components,
3744 const GLfloat *coeffs)
3745{
3746 if (!context->getExtensions().pathRendering)
3747 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003748 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003749 return false;
3750 }
3751
3752 const auto *programObject = context->getProgram(program);
3753 if (!programObject || programObject->isFlaggedForDeletion())
3754 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003755 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003756 return false;
3757 }
3758
3759 if (!programObject->isLinked())
3760 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003761 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003762 return false;
3763 }
3764
3765 switch (genMode)
3766 {
3767 case GL_NONE:
3768 if (components != 0)
3769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003770 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003771 return false;
3772 }
3773 break;
3774
3775 case GL_OBJECT_LINEAR_CHROMIUM:
3776 case GL_EYE_LINEAR_CHROMIUM:
3777 case GL_CONSTANT_CHROMIUM:
3778 if (components < 1 || components > 4)
3779 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003780 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003781 return false;
3782 }
3783 if (!coeffs)
3784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003785 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003786 return false;
3787 }
3788 break;
3789
3790 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003791 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003792 return false;
3793 }
3794
3795 // If the location is -1 then the command is silently ignored
3796 // and no further validation is needed.
3797 if (location == -1)
3798 return true;
3799
Jamie Madillbd044ed2017-06-05 12:59:21 -04003800 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003801
3802 if (!binding.valid)
3803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003804 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003805 return false;
3806 }
3807
3808 if (binding.type != GL_NONE)
3809 {
3810 GLint expectedComponents = 0;
3811 switch (binding.type)
3812 {
3813 case GL_FLOAT:
3814 expectedComponents = 1;
3815 break;
3816 case GL_FLOAT_VEC2:
3817 expectedComponents = 2;
3818 break;
3819 case GL_FLOAT_VEC3:
3820 expectedComponents = 3;
3821 break;
3822 case GL_FLOAT_VEC4:
3823 expectedComponents = 4;
3824 break;
3825 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003826 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003827 InvalidOperation()
3828 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003829 return false;
3830 }
3831 if (expectedComponents != components && genMode != GL_NONE)
3832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003833 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003834 return false;
3835 }
3836 }
3837 return true;
3838}
3839
Geoff Lang97073d12016-04-20 10:42:34 -07003840bool ValidateCopyTextureCHROMIUM(Context *context,
3841 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003842 GLint sourceLevel,
3843 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003844 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003845 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003846 GLint internalFormat,
3847 GLenum destType,
3848 GLboolean unpackFlipY,
3849 GLboolean unpackPremultiplyAlpha,
3850 GLboolean unpackUnmultiplyAlpha)
3851{
3852 if (!context->getExtensions().copyTexture)
3853 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003854 context->handleError(InvalidOperation()
3855 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003856 return false;
3857 }
3858
Geoff Lang4f0e0032017-05-01 16:04:35 -04003859 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003860 if (source == nullptr)
3861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003862 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003863 return false;
3864 }
3865
3866 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3867 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003868 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003869 return false;
3870 }
3871
3872 GLenum sourceTarget = source->getTarget();
3873 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003874
3875 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003876 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003877 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003878 return false;
3879 }
3880
Geoff Lang4f0e0032017-05-01 16:04:35 -04003881 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3882 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3883 if (sourceWidth == 0 || sourceHeight == 0)
3884 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003885 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003886 return false;
3887 }
3888
3889 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3890 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003892 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003893 return false;
3894 }
3895
Geoff Lang63458a32017-10-30 15:16:53 -04003896 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3897 {
3898 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3899 return false;
3900 }
3901
Geoff Lang4f0e0032017-05-01 16:04:35 -04003902 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003903 if (dest == nullptr)
3904 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003905 context->handleError(InvalidValue()
3906 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003907 return false;
3908 }
3909
Geoff Lang4f0e0032017-05-01 16:04:35 -04003910 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003911 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003912 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003913 return false;
3914 }
3915
Geoff Lang4f0e0032017-05-01 16:04:35 -04003916 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3917 sourceHeight))
3918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003919 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003920 return false;
3921 }
3922
Geoff Lang97073d12016-04-20 10:42:34 -07003923 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3924 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003925 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003926 return false;
3927 }
3928
Geoff Lang4f0e0032017-05-01 16:04:35 -04003929 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3930 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003931 context->handleError(
3932 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003933 return false;
3934 }
3935
Geoff Lang97073d12016-04-20 10:42:34 -07003936 if (dest->getImmutableFormat())
3937 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003938 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003939 return false;
3940 }
3941
3942 return true;
3943}
3944
3945bool ValidateCopySubTextureCHROMIUM(Context *context,
3946 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003947 GLint sourceLevel,
3948 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003949 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003950 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003951 GLint xoffset,
3952 GLint yoffset,
3953 GLint x,
3954 GLint y,
3955 GLsizei width,
3956 GLsizei height,
3957 GLboolean unpackFlipY,
3958 GLboolean unpackPremultiplyAlpha,
3959 GLboolean unpackUnmultiplyAlpha)
3960{
3961 if (!context->getExtensions().copyTexture)
3962 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003963 context->handleError(InvalidOperation()
3964 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003965 return false;
3966 }
3967
Geoff Lang4f0e0032017-05-01 16:04:35 -04003968 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003969 if (source == nullptr)
3970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003971 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003972 return false;
3973 }
3974
3975 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3976 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003977 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003978 return false;
3979 }
3980
3981 GLenum sourceTarget = source->getTarget();
3982 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003983
3984 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3985 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003986 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003987 return false;
3988 }
3989
3990 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3991 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07003992 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003993 context->handleError(InvalidValue()
3994 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07003995 return false;
3996 }
3997
3998 if (x < 0 || y < 0)
3999 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004000 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004001 return false;
4002 }
4003
4004 if (width < 0 || height < 0)
4005 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004006 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004007 return false;
4008 }
4009
Geoff Lang4f0e0032017-05-01 16:04:35 -04004010 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4011 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004012 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004013 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004014 return false;
4015 }
4016
Geoff Lang4f0e0032017-05-01 16:04:35 -04004017 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4018 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004019 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004020 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004021 return false;
4022 }
4023
Geoff Lang63458a32017-10-30 15:16:53 -04004024 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4025 {
4026 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4027 return false;
4028 }
4029
Geoff Lang4f0e0032017-05-01 16:04:35 -04004030 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004031 if (dest == nullptr)
4032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004033 context->handleError(InvalidValue()
4034 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Geoff Lang4f0e0032017-05-01 16:04:35 -04004038 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004040 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004041 return false;
4042 }
4043
Geoff Lang4f0e0032017-05-01 16:04:35 -04004044 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07004045 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004046 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004047 return false;
4048 }
4049
Geoff Lang4f0e0032017-05-01 16:04:35 -04004050 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4051 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004052 context
4053 ->handleError(InvalidOperation()
4054 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004055 return false;
4056 }
4057
4058 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4059 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004060 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004061 context->handleError(InvalidOperation()
4062 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004063 return false;
4064 }
4065
4066 if (xoffset < 0 || yoffset < 0)
4067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004068 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004069 return false;
4070 }
4071
Geoff Lang4f0e0032017-05-01 16:04:35 -04004072 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4073 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004074 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004075 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004076 return false;
4077 }
4078
4079 return true;
4080}
4081
Geoff Lang47110bf2016-04-20 11:13:22 -07004082bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4083{
4084 if (!context->getExtensions().copyCompressedTexture)
4085 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004086 context->handleError(InvalidOperation()
4087 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004088 return false;
4089 }
4090
4091 const gl::Texture *source = context->getTexture(sourceId);
4092 if (source == nullptr)
4093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004094 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004095 return false;
4096 }
4097
4098 if (source->getTarget() != GL_TEXTURE_2D)
4099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004100 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004101 return false;
4102 }
4103
4104 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4105 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004106 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004107 return false;
4108 }
4109
4110 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4111 if (!sourceFormat.info->compressed)
4112 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004113 context->handleError(InvalidOperation()
4114 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004115 return false;
4116 }
4117
4118 const gl::Texture *dest = context->getTexture(destId);
4119 if (dest == nullptr)
4120 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004121 context->handleError(InvalidValue()
4122 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004123 return false;
4124 }
4125
4126 if (dest->getTarget() != GL_TEXTURE_2D)
4127 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004128 context->handleError(InvalidValue()
4129 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004130 return false;
4131 }
4132
4133 if (dest->getImmutableFormat())
4134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004135 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004136 return false;
4137 }
4138
4139 return true;
4140}
4141
Martin Radev4c4c8e72016-08-04 12:25:34 +03004142bool ValidateCreateShader(Context *context, GLenum type)
4143{
4144 switch (type)
4145 {
4146 case GL_VERTEX_SHADER:
4147 case GL_FRAGMENT_SHADER:
4148 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004149
Martin Radev4c4c8e72016-08-04 12:25:34 +03004150 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004151 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004152 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004153 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004154 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004155 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004156 break;
4157
Jiawei Shao89be29a2017-11-06 14:36:45 +08004158 case GL_GEOMETRY_SHADER_EXT:
4159 if (!context->getExtensions().geometryShader)
4160 {
4161 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4162 return false;
4163 }
4164 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004165 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004166 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004167 return false;
4168 }
Jamie Madill29639852016-09-02 15:00:09 -04004169
4170 return true;
4171}
4172
4173bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004174 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004175 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004176 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004177 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004178{
4179 if (size < 0)
4180 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004181 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004182 return false;
4183 }
4184
4185 switch (usage)
4186 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004187 case BufferUsage::StreamDraw:
4188 case BufferUsage::StaticDraw:
4189 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004190 break;
4191
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004192 case BufferUsage::StreamRead:
4193 case BufferUsage::StaticRead:
4194 case BufferUsage::DynamicRead:
4195 case BufferUsage::StreamCopy:
4196 case BufferUsage::StaticCopy:
4197 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004198 if (context->getClientMajorVersion() < 3)
4199 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004200 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004201 return false;
4202 }
4203 break;
4204
4205 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004206 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004207 return false;
4208 }
4209
Corentin Walleze4477002017-12-01 14:39:58 -05004210 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004212 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004213 return false;
4214 }
4215
4216 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4217
4218 if (!buffer)
4219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004220 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004221 return false;
4222 }
4223
4224 return true;
4225}
4226
4227bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004228 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004229 GLintptr offset,
4230 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004231 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004232{
Brandon Jones6cad5662017-06-14 13:25:13 -07004233 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004234 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004235 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4236 return false;
4237 }
4238
4239 if (offset < 0)
4240 {
4241 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004242 return false;
4243 }
4244
Corentin Walleze4477002017-12-01 14:39:58 -05004245 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004246 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004247 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004248 return false;
4249 }
4250
4251 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4252
4253 if (!buffer)
4254 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004255 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004256 return false;
4257 }
4258
4259 if (buffer->isMapped())
4260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004261 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004262 return false;
4263 }
4264
4265 // Check for possible overflow of size + offset
4266 angle::CheckedNumeric<size_t> checkedSize(size);
4267 checkedSize += offset;
4268 if (!checkedSize.IsValid())
4269 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004270 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004271 return false;
4272 }
4273
4274 if (size + offset > buffer->getSize())
4275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004276 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004277 return false;
4278 }
4279
Martin Radev4c4c8e72016-08-04 12:25:34 +03004280 return true;
4281}
4282
Geoff Lang111a99e2017-10-17 10:58:41 -04004283bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004284{
Geoff Langc339c4e2016-11-29 10:37:36 -05004285 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004287 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004288 return false;
4289 }
4290
Geoff Lang111a99e2017-10-17 10:58:41 -04004291 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004292 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004293 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004294 return false;
4295 }
4296
4297 return true;
4298}
4299
Jamie Madillef300b12016-10-07 15:12:09 -04004300bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4301{
4302 if (texture < GL_TEXTURE0 ||
4303 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4304 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004305 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004306 return false;
4307 }
4308
4309 return true;
4310}
4311
4312bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4313{
4314 Program *programObject = GetValidProgram(context, program);
4315 if (!programObject)
4316 {
4317 return false;
4318 }
4319
4320 Shader *shaderObject = GetValidShader(context, shader);
4321 if (!shaderObject)
4322 {
4323 return false;
4324 }
4325
4326 switch (shaderObject->getType())
4327 {
4328 case GL_VERTEX_SHADER:
4329 {
4330 if (programObject->getAttachedVertexShader())
4331 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004333 return false;
4334 }
4335 break;
4336 }
4337 case GL_FRAGMENT_SHADER:
4338 {
4339 if (programObject->getAttachedFragmentShader())
4340 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004341 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004342 return false;
4343 }
4344 break;
4345 }
4346 case GL_COMPUTE_SHADER:
4347 {
4348 if (programObject->getAttachedComputeShader())
4349 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004351 return false;
4352 }
4353 break;
4354 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004355 case GL_GEOMETRY_SHADER_EXT:
4356 {
4357 if (programObject->getAttachedGeometryShader())
4358 {
4359 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4360 return false;
4361 }
4362 break;
4363 }
Jamie Madillef300b12016-10-07 15:12:09 -04004364 default:
4365 UNREACHABLE();
4366 break;
4367 }
4368
4369 return true;
4370}
4371
Jamie Madill01a80ee2016-11-07 12:06:18 -05004372bool ValidateBindAttribLocation(ValidationContext *context,
4373 GLuint program,
4374 GLuint index,
4375 const GLchar *name)
4376{
4377 if (index >= MAX_VERTEX_ATTRIBS)
4378 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004379 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004380 return false;
4381 }
4382
4383 if (strncmp(name, "gl_", 3) == 0)
4384 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004385 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004386 return false;
4387 }
4388
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004389 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004390 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004391 const size_t length = strlen(name);
4392
4393 if (!IsValidESSLString(name, length))
4394 {
4395 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4396 // for shader-related entry points
4397 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4398 return false;
4399 }
4400
4401 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4402 {
4403 return false;
4404 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004405 }
4406
Jamie Madill01a80ee2016-11-07 12:06:18 -05004407 return GetValidProgram(context, program) != nullptr;
4408}
4409
Corentin Wallez336129f2017-10-17 15:55:40 -04004410bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004411{
Corentin Walleze4477002017-12-01 14:39:58 -05004412 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004413 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004414 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415 return false;
4416 }
4417
4418 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4419 !context->isBufferGenerated(buffer))
4420 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004422 return false;
4423 }
4424
4425 return true;
4426}
4427
4428bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4429{
Geoff Lange8afa902017-09-27 15:00:43 -04004430 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004431 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004432 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004433 return false;
4434 }
4435
4436 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4437 !context->isFramebufferGenerated(framebuffer))
4438 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004439 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004440 return false;
4441 }
4442
4443 return true;
4444}
4445
4446bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4447{
4448 if (target != GL_RENDERBUFFER)
4449 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004450 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004451 return false;
4452 }
4453
4454 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4455 !context->isRenderbufferGenerated(renderbuffer))
4456 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004457 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004458 return false;
4459 }
4460
4461 return true;
4462}
4463
Geoff Lang50cac572017-09-26 17:37:43 -04004464static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004465{
4466 switch (mode)
4467 {
4468 case GL_FUNC_ADD:
4469 case GL_FUNC_SUBTRACT:
4470 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004471 return true;
4472
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004473 case GL_MIN:
4474 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004475 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004476
4477 default:
4478 return false;
4479 }
4480}
4481
Jamie Madillc1d770e2017-04-13 17:31:24 -04004482bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004483 GLfloat red,
4484 GLfloat green,
4485 GLfloat blue,
4486 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004487{
4488 return true;
4489}
4490
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004491bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4492{
Geoff Lang50cac572017-09-26 17:37:43 -04004493 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004494 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004495 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004496 return false;
4497 }
4498
4499 return true;
4500}
4501
4502bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4503{
Geoff Lang50cac572017-09-26 17:37:43 -04004504 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004505 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004506 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004507 return false;
4508 }
4509
Geoff Lang50cac572017-09-26 17:37:43 -04004510 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004511 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004512 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004513 return false;
4514 }
4515
4516 return true;
4517}
4518
4519bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4520{
4521 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4522}
4523
4524static bool ValidSrcBlendFunc(GLenum srcBlend)
4525{
4526 switch (srcBlend)
4527 {
4528 case GL_ZERO:
4529 case GL_ONE:
4530 case GL_SRC_COLOR:
4531 case GL_ONE_MINUS_SRC_COLOR:
4532 case GL_DST_COLOR:
4533 case GL_ONE_MINUS_DST_COLOR:
4534 case GL_SRC_ALPHA:
4535 case GL_ONE_MINUS_SRC_ALPHA:
4536 case GL_DST_ALPHA:
4537 case GL_ONE_MINUS_DST_ALPHA:
4538 case GL_CONSTANT_COLOR:
4539 case GL_ONE_MINUS_CONSTANT_COLOR:
4540 case GL_CONSTANT_ALPHA:
4541 case GL_ONE_MINUS_CONSTANT_ALPHA:
4542 case GL_SRC_ALPHA_SATURATE:
4543 return true;
4544
4545 default:
4546 return false;
4547 }
4548}
4549
4550static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4551{
4552 switch (dstBlend)
4553 {
4554 case GL_ZERO:
4555 case GL_ONE:
4556 case GL_SRC_COLOR:
4557 case GL_ONE_MINUS_SRC_COLOR:
4558 case GL_DST_COLOR:
4559 case GL_ONE_MINUS_DST_COLOR:
4560 case GL_SRC_ALPHA:
4561 case GL_ONE_MINUS_SRC_ALPHA:
4562 case GL_DST_ALPHA:
4563 case GL_ONE_MINUS_DST_ALPHA:
4564 case GL_CONSTANT_COLOR:
4565 case GL_ONE_MINUS_CONSTANT_COLOR:
4566 case GL_CONSTANT_ALPHA:
4567 case GL_ONE_MINUS_CONSTANT_ALPHA:
4568 return true;
4569
4570 case GL_SRC_ALPHA_SATURATE:
4571 return (contextMajorVersion >= 3);
4572
4573 default:
4574 return false;
4575 }
4576}
4577
4578bool ValidateBlendFuncSeparate(ValidationContext *context,
4579 GLenum srcRGB,
4580 GLenum dstRGB,
4581 GLenum srcAlpha,
4582 GLenum dstAlpha)
4583{
4584 if (!ValidSrcBlendFunc(srcRGB))
4585 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004586 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004587 return false;
4588 }
4589
4590 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4591 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004592 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004593 return false;
4594 }
4595
4596 if (!ValidSrcBlendFunc(srcAlpha))
4597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004599 return false;
4600 }
4601
4602 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4603 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004604 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004605 return false;
4606 }
4607
Frank Henigman146e8a12017-03-02 23:22:37 -05004608 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4609 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004610 {
4611 bool constantColorUsed =
4612 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4613 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4614
4615 bool constantAlphaUsed =
4616 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4617 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4618
4619 if (constantColorUsed && constantAlphaUsed)
4620 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004621 const char *msg;
4622 if (context->getExtensions().webglCompatibility)
4623 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004624 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004625 }
4626 else
4627 {
4628 msg =
4629 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4630 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4631 "implementation.";
4632 ERR() << msg;
4633 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004634 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004635 return false;
4636 }
4637 }
4638
4639 return true;
4640}
4641
Geoff Langc339c4e2016-11-29 10:37:36 -05004642bool ValidateGetString(Context *context, GLenum name)
4643{
4644 switch (name)
4645 {
4646 case GL_VENDOR:
4647 case GL_RENDERER:
4648 case GL_VERSION:
4649 case GL_SHADING_LANGUAGE_VERSION:
4650 case GL_EXTENSIONS:
4651 break;
4652
4653 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4654 if (!context->getExtensions().requestExtension)
4655 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004656 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004657 return false;
4658 }
4659 break;
4660
4661 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004662 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004663 return false;
4664 }
4665
4666 return true;
4667}
4668
Geoff Lang47c48082016-12-07 15:38:13 -05004669bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4670{
4671 if (width <= 0.0f || isNaN(width))
4672 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004673 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004674 return false;
4675 }
4676
4677 return true;
4678}
4679
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004680bool ValidateVertexAttribPointer(ValidationContext *context,
4681 GLuint index,
4682 GLint size,
4683 GLenum type,
4684 GLboolean normalized,
4685 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004686 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004687{
Shao80957d92017-02-20 21:25:59 +08004688 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004689 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004690 return false;
4691 }
4692
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693 if (stride < 0)
4694 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004695 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004696 return false;
4697 }
4698
Shao80957d92017-02-20 21:25:59 +08004699 const Caps &caps = context->getCaps();
4700 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004701 {
Shao80957d92017-02-20 21:25:59 +08004702 if (stride > caps.maxVertexAttribStride)
4703 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004704 context->handleError(InvalidValue()
4705 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004706 return false;
4707 }
4708
4709 if (index >= caps.maxVertexAttribBindings)
4710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004711 context->handleError(InvalidValue()
4712 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004713 return false;
4714 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004715 }
4716
4717 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4718 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4719 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4720 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004721 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4722 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004723 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4724 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004726 context
4727 ->handleError(InvalidOperation()
4728 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 return false;
4730 }
4731
4732 if (context->getExtensions().webglCompatibility)
4733 {
4734 // WebGL 1.0 [Section 6.14] Fixed point support
4735 // The WebGL API does not support the GL_FIXED data type.
4736 if (type == GL_FIXED)
4737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004738 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004739 return false;
4740 }
4741
Geoff Lang2d62ab72017-03-23 16:54:40 -04004742 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 return false;
4745 }
4746 }
4747
4748 return true;
4749}
4750
Jamie Madill876429b2017-04-20 15:46:24 -04004751bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004752{
4753 if (context->getExtensions().webglCompatibility && zNear > zFar)
4754 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004755 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004756 return false;
4757 }
4758
4759 return true;
4760}
4761
Jamie Madille8fb6402017-02-14 17:56:40 -05004762bool ValidateRenderbufferStorage(ValidationContext *context,
4763 GLenum target,
4764 GLenum internalformat,
4765 GLsizei width,
4766 GLsizei height)
4767{
4768 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4769 height);
4770}
4771
4772bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4773 GLenum target,
4774 GLsizei samples,
4775 GLenum internalformat,
4776 GLsizei width,
4777 GLsizei height)
4778{
4779 if (!context->getExtensions().framebufferMultisample)
4780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004781 context->handleError(InvalidOperation()
4782 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004783 return false;
4784 }
4785
4786 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4787 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4788 // generated.
4789 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4790 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004791 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004792 return false;
4793 }
4794
4795 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4796 // the specified storage. This is different than ES 3.0 in which a sample number higher
4797 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4798 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4799 if (context->getClientMajorVersion() >= 3)
4800 {
4801 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4802 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4803 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004804 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004805 return false;
4806 }
4807 }
4808
4809 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4810 width, height);
4811}
4812
Jamie Madillc1d770e2017-04-13 17:31:24 -04004813bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4814{
Geoff Lange8afa902017-09-27 15:00:43 -04004815 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004816 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004817 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004818 return false;
4819 }
4820
4821 return true;
4822}
4823
4824bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004825 GLfloat red,
4826 GLfloat green,
4827 GLfloat blue,
4828 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004829{
4830 return true;
4831}
4832
Jamie Madill876429b2017-04-20 15:46:24 -04004833bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004834{
4835 return true;
4836}
4837
4838bool ValidateClearStencil(ValidationContext *context, GLint s)
4839{
4840 return true;
4841}
4842
4843bool ValidateColorMask(ValidationContext *context,
4844 GLboolean red,
4845 GLboolean green,
4846 GLboolean blue,
4847 GLboolean alpha)
4848{
4849 return true;
4850}
4851
4852bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4853{
4854 return true;
4855}
4856
4857bool ValidateCreateProgram(ValidationContext *context)
4858{
4859 return true;
4860}
4861
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004862bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863{
4864 switch (mode)
4865 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004866 case CullFaceMode::Front:
4867 case CullFaceMode::Back:
4868 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869 break;
4870
4871 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004872 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873 return false;
4874 }
4875
4876 return true;
4877}
4878
4879bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4880{
4881 if (program == 0)
4882 {
4883 return false;
4884 }
4885
4886 if (!context->getProgram(program))
4887 {
4888 if (context->getShader(program))
4889 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004890 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004891 return false;
4892 }
4893 else
4894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004895 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896 return false;
4897 }
4898 }
4899
4900 return true;
4901}
4902
4903bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4904{
4905 if (shader == 0)
4906 {
4907 return false;
4908 }
4909
4910 if (!context->getShader(shader))
4911 {
4912 if (context->getProgram(shader))
4913 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004914 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004915 return false;
4916 }
4917 else
4918 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004919 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004920 return false;
4921 }
4922 }
4923
4924 return true;
4925}
4926
4927bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4928{
4929 switch (func)
4930 {
4931 case GL_NEVER:
4932 case GL_ALWAYS:
4933 case GL_LESS:
4934 case GL_LEQUAL:
4935 case GL_EQUAL:
4936 case GL_GREATER:
4937 case GL_GEQUAL:
4938 case GL_NOTEQUAL:
4939 break;
4940
4941 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004943 return false;
4944 }
4945
4946 return true;
4947}
4948
4949bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4950{
4951 return true;
4952}
4953
4954bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4955{
4956 Program *programObject = GetValidProgram(context, program);
4957 if (!programObject)
4958 {
4959 return false;
4960 }
4961
4962 Shader *shaderObject = GetValidShader(context, shader);
4963 if (!shaderObject)
4964 {
4965 return false;
4966 }
4967
4968 const Shader *attachedShader = nullptr;
4969
4970 switch (shaderObject->getType())
4971 {
4972 case GL_VERTEX_SHADER:
4973 {
4974 attachedShader = programObject->getAttachedVertexShader();
4975 break;
4976 }
4977 case GL_FRAGMENT_SHADER:
4978 {
4979 attachedShader = programObject->getAttachedFragmentShader();
4980 break;
4981 }
4982 case GL_COMPUTE_SHADER:
4983 {
4984 attachedShader = programObject->getAttachedComputeShader();
4985 break;
4986 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004987 case GL_GEOMETRY_SHADER_EXT:
4988 {
4989 attachedShader = programObject->getAttachedGeometryShader();
4990 break;
4991 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004992 default:
4993 UNREACHABLE();
4994 return false;
4995 }
4996
4997 if (attachedShader != shaderObject)
4998 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004999 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005000 return false;
5001 }
5002
5003 return true;
5004}
5005
5006bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5007{
5008 if (index >= MAX_VERTEX_ATTRIBS)
5009 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005010 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011 return false;
5012 }
5013
5014 return true;
5015}
5016
5017bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5018{
5019 if (index >= MAX_VERTEX_ATTRIBS)
5020 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005021 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022 return false;
5023 }
5024
5025 return true;
5026}
5027
5028bool ValidateFinish(ValidationContext *context)
5029{
5030 return true;
5031}
5032
5033bool ValidateFlush(ValidationContext *context)
5034{
5035 return true;
5036}
5037
5038bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5039{
5040 switch (mode)
5041 {
5042 case GL_CW:
5043 case GL_CCW:
5044 break;
5045 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005047 return false;
5048 }
5049
5050 return true;
5051}
5052
5053bool ValidateGetActiveAttrib(ValidationContext *context,
5054 GLuint program,
5055 GLuint index,
5056 GLsizei bufsize,
5057 GLsizei *length,
5058 GLint *size,
5059 GLenum *type,
5060 GLchar *name)
5061{
5062 if (bufsize < 0)
5063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005064 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005065 return false;
5066 }
5067
5068 Program *programObject = GetValidProgram(context, program);
5069
5070 if (!programObject)
5071 {
5072 return false;
5073 }
5074
5075 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5076 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005077 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005078 return false;
5079 }
5080
5081 return true;
5082}
5083
5084bool ValidateGetActiveUniform(ValidationContext *context,
5085 GLuint program,
5086 GLuint index,
5087 GLsizei bufsize,
5088 GLsizei *length,
5089 GLint *size,
5090 GLenum *type,
5091 GLchar *name)
5092{
5093 if (bufsize < 0)
5094 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005095 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005096 return false;
5097 }
5098
5099 Program *programObject = GetValidProgram(context, program);
5100
5101 if (!programObject)
5102 {
5103 return false;
5104 }
5105
5106 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5107 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005108 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005109 return false;
5110 }
5111
5112 return true;
5113}
5114
5115bool ValidateGetAttachedShaders(ValidationContext *context,
5116 GLuint program,
5117 GLsizei maxcount,
5118 GLsizei *count,
5119 GLuint *shaders)
5120{
5121 if (maxcount < 0)
5122 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005123 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005124 return false;
5125 }
5126
5127 Program *programObject = GetValidProgram(context, program);
5128
5129 if (!programObject)
5130 {
5131 return false;
5132 }
5133
5134 return true;
5135}
5136
5137bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5138{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005139 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5140 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005141 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005142 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005143 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005144 return false;
5145 }
5146
Jamie Madillc1d770e2017-04-13 17:31:24 -04005147 Program *programObject = GetValidProgram(context, program);
5148
5149 if (!programObject)
5150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005151 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152 return false;
5153 }
5154
5155 if (!programObject->isLinked())
5156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005158 return false;
5159 }
5160
5161 return true;
5162}
5163
5164bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5165{
5166 GLenum nativeType;
5167 unsigned int numParams = 0;
5168 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5169}
5170
5171bool ValidateGetError(ValidationContext *context)
5172{
5173 return true;
5174}
5175
5176bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5177{
5178 GLenum nativeType;
5179 unsigned int numParams = 0;
5180 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5181}
5182
5183bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5184{
5185 GLenum nativeType;
5186 unsigned int numParams = 0;
5187 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5188}
5189
5190bool ValidateGetProgramInfoLog(ValidationContext *context,
5191 GLuint program,
5192 GLsizei bufsize,
5193 GLsizei *length,
5194 GLchar *infolog)
5195{
5196 if (bufsize < 0)
5197 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005198 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199 return false;
5200 }
5201
5202 Program *programObject = GetValidProgram(context, program);
5203 if (!programObject)
5204 {
5205 return false;
5206 }
5207
5208 return true;
5209}
5210
5211bool ValidateGetShaderInfoLog(ValidationContext *context,
5212 GLuint shader,
5213 GLsizei bufsize,
5214 GLsizei *length,
5215 GLchar *infolog)
5216{
5217 if (bufsize < 0)
5218 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005219 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005220 return false;
5221 }
5222
5223 Shader *shaderObject = GetValidShader(context, shader);
5224 if (!shaderObject)
5225 {
5226 return false;
5227 }
5228
5229 return true;
5230}
5231
5232bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5233 GLenum shadertype,
5234 GLenum precisiontype,
5235 GLint *range,
5236 GLint *precision)
5237{
5238 switch (shadertype)
5239 {
5240 case GL_VERTEX_SHADER:
5241 case GL_FRAGMENT_SHADER:
5242 break;
5243 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005244 context->handleError(InvalidOperation()
5245 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005246 return false;
5247 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005248 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005249 return false;
5250 }
5251
5252 switch (precisiontype)
5253 {
5254 case GL_LOW_FLOAT:
5255 case GL_MEDIUM_FLOAT:
5256 case GL_HIGH_FLOAT:
5257 case GL_LOW_INT:
5258 case GL_MEDIUM_INT:
5259 case GL_HIGH_INT:
5260 break;
5261
5262 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005263 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005264 return false;
5265 }
5266
5267 return true;
5268}
5269
5270bool ValidateGetShaderSource(ValidationContext *context,
5271 GLuint shader,
5272 GLsizei bufsize,
5273 GLsizei *length,
5274 GLchar *source)
5275{
5276 if (bufsize < 0)
5277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005278 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005279 return false;
5280 }
5281
5282 Shader *shaderObject = GetValidShader(context, shader);
5283 if (!shaderObject)
5284 {
5285 return false;
5286 }
5287
5288 return true;
5289}
5290
5291bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5292{
5293 if (strstr(name, "gl_") == name)
5294 {
5295 return false;
5296 }
5297
Geoff Langfc32e8b2017-05-31 14:16:59 -04005298 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5299 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005300 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005302 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005303 return false;
5304 }
5305
Jamie Madillc1d770e2017-04-13 17:31:24 -04005306 Program *programObject = GetValidProgram(context, program);
5307
5308 if (!programObject)
5309 {
5310 return false;
5311 }
5312
5313 if (!programObject->isLinked())
5314 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005315 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005316 return false;
5317 }
5318
5319 return true;
5320}
5321
5322bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5323{
5324 switch (mode)
5325 {
5326 case GL_FASTEST:
5327 case GL_NICEST:
5328 case GL_DONT_CARE:
5329 break;
5330
5331 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005332 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005333 return false;
5334 }
5335
5336 switch (target)
5337 {
5338 case GL_GENERATE_MIPMAP_HINT:
5339 break;
5340
Geoff Lange7bd2182017-06-16 16:13:13 -04005341 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5342 if (context->getClientVersion() < ES_3_0 &&
5343 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005344 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005345 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005346 return false;
5347 }
5348 break;
5349
5350 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005351 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005352 return false;
5353 }
5354
5355 return true;
5356}
5357
5358bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5359{
5360 return true;
5361}
5362
5363bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5364{
5365 return true;
5366}
5367
5368bool ValidateIsProgram(ValidationContext *context, GLuint program)
5369{
5370 return true;
5371}
5372
5373bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5374{
5375 return true;
5376}
5377
5378bool ValidateIsShader(ValidationContext *context, GLuint shader)
5379{
5380 return true;
5381}
5382
5383bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5384{
5385 return true;
5386}
5387
5388bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5389{
5390 if (context->getClientMajorVersion() < 3)
5391 {
5392 switch (pname)
5393 {
5394 case GL_UNPACK_IMAGE_HEIGHT:
5395 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005396 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397 return false;
5398
5399 case GL_UNPACK_ROW_LENGTH:
5400 case GL_UNPACK_SKIP_ROWS:
5401 case GL_UNPACK_SKIP_PIXELS:
5402 if (!context->getExtensions().unpackSubimage)
5403 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005404 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405 return false;
5406 }
5407 break;
5408
5409 case GL_PACK_ROW_LENGTH:
5410 case GL_PACK_SKIP_ROWS:
5411 case GL_PACK_SKIP_PIXELS:
5412 if (!context->getExtensions().packSubimage)
5413 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005414 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005415 return false;
5416 }
5417 break;
5418 }
5419 }
5420
5421 if (param < 0)
5422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005423 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005424 return false;
5425 }
5426
5427 switch (pname)
5428 {
5429 case GL_UNPACK_ALIGNMENT:
5430 if (param != 1 && param != 2 && param != 4 && param != 8)
5431 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005432 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005433 return false;
5434 }
5435 break;
5436
5437 case GL_PACK_ALIGNMENT:
5438 if (param != 1 && param != 2 && param != 4 && param != 8)
5439 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005440 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005441 return false;
5442 }
5443 break;
5444
5445 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005446 if (!context->getExtensions().packReverseRowOrder)
5447 {
5448 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5449 }
5450 break;
5451
Jamie Madillc1d770e2017-04-13 17:31:24 -04005452 case GL_UNPACK_ROW_LENGTH:
5453 case GL_UNPACK_IMAGE_HEIGHT:
5454 case GL_UNPACK_SKIP_IMAGES:
5455 case GL_UNPACK_SKIP_ROWS:
5456 case GL_UNPACK_SKIP_PIXELS:
5457 case GL_PACK_ROW_LENGTH:
5458 case GL_PACK_SKIP_ROWS:
5459 case GL_PACK_SKIP_PIXELS:
5460 break;
5461
5462 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005463 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464 return false;
5465 }
5466
5467 return true;
5468}
5469
5470bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5471{
5472 return true;
5473}
5474
5475bool ValidateReleaseShaderCompiler(ValidationContext *context)
5476{
5477 return true;
5478}
5479
Jamie Madill876429b2017-04-20 15:46:24 -04005480bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481{
5482 return true;
5483}
5484
5485bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5486{
5487 if (width < 0 || height < 0)
5488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005489 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005490 return false;
5491 }
5492
5493 return true;
5494}
5495
5496bool ValidateShaderBinary(ValidationContext *context,
5497 GLsizei n,
5498 const GLuint *shaders,
5499 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005500 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005501 GLsizei length)
5502{
5503 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5504 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5505 shaderBinaryFormats.end())
5506 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005507 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005508 return false;
5509 }
5510
5511 return true;
5512}
5513
5514bool ValidateShaderSource(ValidationContext *context,
5515 GLuint shader,
5516 GLsizei count,
5517 const GLchar *const *string,
5518 const GLint *length)
5519{
5520 if (count < 0)
5521 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005522 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005523 return false;
5524 }
5525
Geoff Langfc32e8b2017-05-31 14:16:59 -04005526 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5527 // shader-related entry points
5528 if (context->getExtensions().webglCompatibility)
5529 {
5530 for (GLsizei i = 0; i < count; i++)
5531 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005532 size_t len =
5533 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005534
5535 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005536 if (!IsValidESSLShaderSourceString(string[i], len,
5537 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005538 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005539 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005540 return false;
5541 }
5542 }
5543 }
5544
Jamie Madillc1d770e2017-04-13 17:31:24 -04005545 Shader *shaderObject = GetValidShader(context, shader);
5546 if (!shaderObject)
5547 {
5548 return false;
5549 }
5550
5551 return true;
5552}
5553
5554bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5555{
5556 if (!IsValidStencilFunc(func))
5557 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005558 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005559 return false;
5560 }
5561
5562 return true;
5563}
5564
5565bool ValidateStencilFuncSeparate(ValidationContext *context,
5566 GLenum face,
5567 GLenum func,
5568 GLint ref,
5569 GLuint mask)
5570{
5571 if (!IsValidStencilFace(face))
5572 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005573 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005574 return false;
5575 }
5576
5577 if (!IsValidStencilFunc(func))
5578 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005579 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005580 return false;
5581 }
5582
5583 return true;
5584}
5585
5586bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5587{
5588 return true;
5589}
5590
5591bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5592{
5593 if (!IsValidStencilFace(face))
5594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596 return false;
5597 }
5598
5599 return true;
5600}
5601
5602bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5603{
5604 if (!IsValidStencilOp(fail))
5605 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005606 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005607 return false;
5608 }
5609
5610 if (!IsValidStencilOp(zfail))
5611 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005612 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005613 return false;
5614 }
5615
5616 if (!IsValidStencilOp(zpass))
5617 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005618 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005619 return false;
5620 }
5621
5622 return true;
5623}
5624
5625bool ValidateStencilOpSeparate(ValidationContext *context,
5626 GLenum face,
5627 GLenum fail,
5628 GLenum zfail,
5629 GLenum zpass)
5630{
5631 if (!IsValidStencilFace(face))
5632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005634 return false;
5635 }
5636
5637 return ValidateStencilOp(context, fail, zfail, zpass);
5638}
5639
5640bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5641{
5642 return ValidateUniform(context, GL_FLOAT, location, 1);
5643}
5644
5645bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5646{
5647 return ValidateUniform(context, GL_FLOAT, location, count);
5648}
5649
Jamie Madillbe849e42017-05-02 15:49:00 -04005650bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5651{
5652 return ValidateUniform1iv(context, location, 1, &x);
5653}
5654
Jamie Madillc1d770e2017-04-13 17:31:24 -04005655bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5656{
5657 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5658}
5659
5660bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5661{
5662 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5663}
5664
5665bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5666{
5667 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5668}
5669
5670bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5671{
5672 return ValidateUniform(context, GL_INT_VEC2, location, count);
5673}
5674
5675bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5676{
5677 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5678}
5679
5680bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5681{
5682 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5683}
5684
5685bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5686{
5687 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5688}
5689
5690bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5691{
5692 return ValidateUniform(context, GL_INT_VEC3, location, count);
5693}
5694
5695bool ValidateUniform4f(ValidationContext *context,
5696 GLint location,
5697 GLfloat x,
5698 GLfloat y,
5699 GLfloat z,
5700 GLfloat w)
5701{
5702 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5703}
5704
5705bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5706{
5707 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5708}
5709
5710bool ValidateUniform4i(ValidationContext *context,
5711 GLint location,
5712 GLint x,
5713 GLint y,
5714 GLint z,
5715 GLint w)
5716{
5717 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5718}
5719
5720bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5721{
5722 return ValidateUniform(context, GL_INT_VEC4, location, count);
5723}
5724
5725bool ValidateUniformMatrix2fv(ValidationContext *context,
5726 GLint location,
5727 GLsizei count,
5728 GLboolean transpose,
5729 const GLfloat *value)
5730{
5731 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5732}
5733
5734bool ValidateUniformMatrix3fv(ValidationContext *context,
5735 GLint location,
5736 GLsizei count,
5737 GLboolean transpose,
5738 const GLfloat *value)
5739{
5740 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5741}
5742
5743bool ValidateUniformMatrix4fv(ValidationContext *context,
5744 GLint location,
5745 GLsizei count,
5746 GLboolean transpose,
5747 const GLfloat *value)
5748{
5749 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5750}
5751
5752bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5753{
5754 Program *programObject = GetValidProgram(context, program);
5755
5756 if (!programObject)
5757 {
5758 return false;
5759 }
5760
5761 return true;
5762}
5763
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
5769bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
5774bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5775{
5776 return ValidateVertexAttribIndex(context, index);
5777}
5778
5779bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5780{
5781 return ValidateVertexAttribIndex(context, index);
5782}
5783
5784bool ValidateVertexAttrib3f(ValidationContext *context,
5785 GLuint index,
5786 GLfloat x,
5787 GLfloat y,
5788 GLfloat z)
5789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
5793bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
5798bool ValidateVertexAttrib4f(ValidationContext *context,
5799 GLuint index,
5800 GLfloat x,
5801 GLfloat y,
5802 GLfloat z,
5803 GLfloat w)
5804{
5805 return ValidateVertexAttribIndex(context, index);
5806}
5807
5808bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5809{
5810 return ValidateVertexAttribIndex(context, index);
5811}
5812
5813bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5814{
5815 if (width < 0 || height < 0)
5816 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005817 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005818 return false;
5819 }
5820
5821 return true;
5822}
5823
5824bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5825{
5826 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5827}
5828
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005829bool ValidateDrawElements(ValidationContext *context,
5830 GLenum mode,
5831 GLsizei count,
5832 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005833 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005834{
5835 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5836}
5837
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005838bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005839 GLenum target,
5840 GLenum attachment,
5841 GLenum pname,
5842 GLint *params)
5843{
5844 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5845 nullptr);
5846}
5847
5848bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5849{
5850 return ValidateGetProgramivBase(context, program, pname, nullptr);
5851}
5852
5853bool ValidateCopyTexImage2D(ValidationContext *context,
5854 GLenum target,
5855 GLint level,
5856 GLenum internalformat,
5857 GLint x,
5858 GLint y,
5859 GLsizei width,
5860 GLsizei height,
5861 GLint border)
5862{
5863 if (context->getClientMajorVersion() < 3)
5864 {
5865 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5866 0, x, y, width, height, border);
5867 }
5868
5869 ASSERT(context->getClientMajorVersion() == 3);
5870 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5871 0, x, y, width, height, border);
5872}
5873
5874bool ValidateCopyTexSubImage2D(Context *context,
5875 GLenum target,
5876 GLint level,
5877 GLint xoffset,
5878 GLint yoffset,
5879 GLint x,
5880 GLint y,
5881 GLsizei width,
5882 GLsizei height)
5883{
5884 if (context->getClientMajorVersion() < 3)
5885 {
5886 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5887 yoffset, x, y, width, height, 0);
5888 }
5889
5890 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5891 yoffset, 0, x, y, width, height, 0);
5892}
5893
5894bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5895{
5896 return ValidateGenOrDelete(context, n);
5897}
5898
5899bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5900{
5901 return ValidateGenOrDelete(context, n);
5902}
5903
5904bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5905{
5906 return ValidateGenOrDelete(context, n);
5907}
5908
5909bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5910{
5911 return ValidateGenOrDelete(context, n);
5912}
5913
5914bool ValidateDisable(Context *context, GLenum cap)
5915{
5916 if (!ValidCap(context, cap, false))
5917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005918 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005919 return false;
5920 }
5921
5922 return true;
5923}
5924
5925bool ValidateEnable(Context *context, GLenum cap)
5926{
5927 if (!ValidCap(context, cap, false))
5928 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005929 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005930 return false;
5931 }
5932
5933 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5934 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5935 {
5936 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005937 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005938
5939 // We also output an error message to the debugger window if tracing is active, so that
5940 // developers can see the error message.
5941 ERR() << errorMessage;
5942 return false;
5943 }
5944
5945 return true;
5946}
5947
5948bool ValidateFramebufferRenderbuffer(Context *context,
5949 GLenum target,
5950 GLenum attachment,
5951 GLenum renderbuffertarget,
5952 GLuint renderbuffer)
5953{
Geoff Lange8afa902017-09-27 15:00:43 -04005954 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005955 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005956 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5957 return false;
5958 }
5959
5960 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5961 {
5962 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005963 return false;
5964 }
5965
5966 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5967 renderbuffertarget, renderbuffer);
5968}
5969
5970bool ValidateFramebufferTexture2D(Context *context,
5971 GLenum target,
5972 GLenum attachment,
5973 GLenum textarget,
5974 GLuint texture,
5975 GLint level)
5976{
5977 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5978 // extension
5979 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5980 level != 0)
5981 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005982 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005983 return false;
5984 }
5985
5986 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5987 {
5988 return false;
5989 }
5990
5991 if (texture != 0)
5992 {
5993 gl::Texture *tex = context->getTexture(texture);
5994 ASSERT(tex);
5995
5996 const gl::Caps &caps = context->getCaps();
5997
5998 switch (textarget)
5999 {
6000 case GL_TEXTURE_2D:
6001 {
6002 if (level > gl::log2(caps.max2DTextureSize))
6003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006004 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006005 return false;
6006 }
6007 if (tex->getTarget() != GL_TEXTURE_2D)
6008 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006009 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006010 return false;
6011 }
6012 }
6013 break;
6014
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006015 case GL_TEXTURE_RECTANGLE_ANGLE:
6016 {
6017 if (level != 0)
6018 {
6019 context->handleError(InvalidValue());
6020 return false;
6021 }
6022 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
6023 {
6024 context->handleError(InvalidOperation()
6025 << "Textarget must match the texture target type.");
6026 return false;
6027 }
6028 }
6029 break;
6030
Jamie Madillbe849e42017-05-02 15:49:00 -04006031 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
6032 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
6033 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
6034 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
6035 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
6036 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
6037 {
6038 if (level > gl::log2(caps.maxCubeMapTextureSize))
6039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006040 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 return false;
6042 }
6043 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
6044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006045 context->handleError(InvalidOperation()
6046 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 return false;
6048 }
6049 }
6050 break;
6051
6052 case GL_TEXTURE_2D_MULTISAMPLE:
6053 {
6054 if (context->getClientVersion() < ES_3_1)
6055 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006056 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 return false;
6058 }
6059
6060 if (level != 0)
6061 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006062 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006063 return false;
6064 }
6065 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
6066 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006067 context->handleError(InvalidOperation()
6068 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006069 return false;
6070 }
6071 }
6072 break;
6073
6074 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006075 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 return false;
6077 }
6078
6079 const Format &format = tex->getFormat(textarget, level);
6080 if (format.info->compressed)
6081 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006082 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006083 return false;
6084 }
6085 }
6086
6087 return true;
6088}
6089
6090bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6091{
6092 return ValidateGenOrDelete(context, n);
6093}
6094
6095bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6096{
6097 return ValidateGenOrDelete(context, n);
6098}
6099
6100bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6101{
6102 return ValidateGenOrDelete(context, n);
6103}
6104
6105bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6106{
6107 return ValidateGenOrDelete(context, n);
6108}
6109
6110bool ValidateGenerateMipmap(Context *context, GLenum target)
6111{
6112 if (!ValidTextureTarget(context, target))
6113 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006114 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006115 return false;
6116 }
6117
6118 Texture *texture = context->getTargetTexture(target);
6119
6120 if (texture == nullptr)
6121 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006122 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006123 return false;
6124 }
6125
6126 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6127
6128 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6129 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6130 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006132 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006133 return false;
6134 }
6135
6136 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
Geoff Lang536eca12017-09-13 11:23:35 -04006137 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6138 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6139 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006140 {
6141 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6142 return false;
6143 }
6144
Geoff Lang536eca12017-09-13 11:23:35 -04006145 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6146 bool formatUnsized = !format.sized;
6147 bool formatColorRenderableAndFilterable =
6148 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6149 format.renderSupport(context->getClientVersion(), context->getExtensions());
6150 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006151 {
Geoff Lang536eca12017-09-13 11:23:35 -04006152 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006153 return false;
6154 }
6155
Geoff Lang536eca12017-09-13 11:23:35 -04006156 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6157 // generation
6158 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6159 {
6160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6161 return false;
6162 }
6163
6164 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6165 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006166 bool supportsSRGBMipmapGeneration =
6167 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006168 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006169 {
Geoff Lang536eca12017-09-13 11:23:35 -04006170 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006171 return false;
6172 }
6173
6174 // Non-power of 2 ES2 check
6175 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6176 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6177 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6178 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006179 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6180 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006181 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006182 return false;
6183 }
6184
6185 // Cube completeness check
6186 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6187 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006188 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006189 return false;
6190 }
6191
6192 return true;
6193}
6194
6195bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006196 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006197 GLenum pname,
6198 GLint *params)
6199{
6200 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6201}
6202
6203bool ValidateGetRenderbufferParameteriv(Context *context,
6204 GLenum target,
6205 GLenum pname,
6206 GLint *params)
6207{
6208 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6209}
6210
6211bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6212{
6213 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6214}
6215
6216bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6217{
6218 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6219}
6220
6221bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6222{
6223 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6224}
6225
6226bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6227{
6228 return ValidateGetUniformBase(context, program, location);
6229}
6230
6231bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6232{
6233 return ValidateGetUniformBase(context, program, location);
6234}
6235
6236bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6237{
6238 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6239}
6240
6241bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6242{
6243 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6244}
6245
6246bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6247{
6248 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6249}
6250
6251bool ValidateIsEnabled(Context *context, GLenum cap)
6252{
6253 if (!ValidCap(context, cap, true))
6254 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006255 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006256 return false;
6257 }
6258
6259 return true;
6260}
6261
6262bool ValidateLinkProgram(Context *context, GLuint program)
6263{
6264 if (context->hasActiveTransformFeedback(program))
6265 {
6266 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006267 context->handleError(InvalidOperation() << "Cannot link program while program is "
6268 "associated with an active transform "
6269 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006270 return false;
6271 }
6272
6273 Program *programObject = GetValidProgram(context, program);
6274 if (!programObject)
6275 {
6276 return false;
6277 }
6278
6279 return true;
6280}
6281
Jamie Madill4928b7c2017-06-20 12:57:39 -04006282bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006283 GLint x,
6284 GLint y,
6285 GLsizei width,
6286 GLsizei height,
6287 GLenum format,
6288 GLenum type,
6289 void *pixels)
6290{
6291 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6292 nullptr, pixels);
6293}
6294
6295bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6296{
6297 return ValidateTexParameterBase(context, target, pname, -1, &param);
6298}
6299
6300bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6301{
6302 return ValidateTexParameterBase(context, target, pname, -1, params);
6303}
6304
6305bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6306{
6307 return ValidateTexParameterBase(context, target, pname, -1, &param);
6308}
6309
6310bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6311{
6312 return ValidateTexParameterBase(context, target, pname, -1, params);
6313}
6314
6315bool ValidateUseProgram(Context *context, GLuint program)
6316{
6317 if (program != 0)
6318 {
6319 Program *programObject = context->getProgram(program);
6320 if (!programObject)
6321 {
6322 // ES 3.1.0 section 7.3 page 72
6323 if (context->getShader(program))
6324 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006325 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006326 return false;
6327 }
6328 else
6329 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006330 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006331 return false;
6332 }
6333 }
6334 if (!programObject->isLinked())
6335 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006337 return false;
6338 }
6339 }
6340 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6341 {
6342 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006343 context
6344 ->handleError(InvalidOperation()
6345 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006346 return false;
6347 }
6348
6349 return true;
6350}
6351
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006352bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6353{
6354 if (!context->getExtensions().fence)
6355 {
6356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6357 return false;
6358 }
6359
6360 if (n < 0)
6361 {
6362 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6363 return false;
6364 }
6365
6366 return true;
6367}
6368
6369bool ValidateFinishFenceNV(Context *context, GLuint fence)
6370{
6371 if (!context->getExtensions().fence)
6372 {
6373 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6374 return false;
6375 }
6376
6377 FenceNV *fenceObject = context->getFenceNV(fence);
6378
6379 if (fenceObject == nullptr)
6380 {
6381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6382 return false;
6383 }
6384
6385 if (!fenceObject->isSet())
6386 {
6387 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6388 return false;
6389 }
6390
6391 return true;
6392}
6393
6394bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6395{
6396 if (!context->getExtensions().fence)
6397 {
6398 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6399 return false;
6400 }
6401
6402 if (n < 0)
6403 {
6404 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6405 return false;
6406 }
6407
6408 return true;
6409}
6410
6411bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6412{
6413 if (!context->getExtensions().fence)
6414 {
6415 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6416 return false;
6417 }
6418
6419 FenceNV *fenceObject = context->getFenceNV(fence);
6420
6421 if (fenceObject == nullptr)
6422 {
6423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6424 return false;
6425 }
6426
6427 if (!fenceObject->isSet())
6428 {
6429 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6430 return false;
6431 }
6432
6433 switch (pname)
6434 {
6435 case GL_FENCE_STATUS_NV:
6436 case GL_FENCE_CONDITION_NV:
6437 break;
6438
6439 default:
6440 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6441 return false;
6442 }
6443
6444 return true;
6445}
6446
6447bool ValidateGetGraphicsResetStatusEXT(Context *context)
6448{
6449 if (!context->getExtensions().robustness)
6450 {
6451 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6452 return false;
6453 }
6454
6455 return true;
6456}
6457
6458bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6459 GLuint shader,
6460 GLsizei bufsize,
6461 GLsizei *length,
6462 GLchar *source)
6463{
6464 if (!context->getExtensions().translatedShaderSource)
6465 {
6466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6467 return false;
6468 }
6469
6470 if (bufsize < 0)
6471 {
6472 context->handleError(InvalidValue());
6473 return false;
6474 }
6475
6476 Shader *shaderObject = context->getShader(shader);
6477
6478 if (!shaderObject)
6479 {
6480 context->handleError(InvalidOperation());
6481 return false;
6482 }
6483
6484 return true;
6485}
6486
6487bool ValidateIsFenceNV(Context *context, GLuint fence)
6488{
6489 if (!context->getExtensions().fence)
6490 {
6491 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6492 return false;
6493 }
6494
6495 return true;
6496}
6497
Jamie Madillc29968b2016-01-20 11:17:23 -05006498} // namespace gl