blob: 64cbb685d46c02d581f74a829ac3608d49cf95b7 [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 Madillef300b12016-10-07 15:12:09 -040018#include "libANGLE/Framebuffer.h"
19#include "libANGLE/FramebufferAttachment.h"
20#include "libANGLE/Renderbuffer.h"
21#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040022#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040023#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040024#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040025#include "libANGLE/formatutils.h"
26#include "libANGLE/validationES.h"
27#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040028
29namespace gl
30{
31
Jamie Madillc29968b2016-01-20 11:17:23 -050032namespace
33{
34
35bool IsPartialBlit(gl::Context *context,
36 const FramebufferAttachment *readBuffer,
37 const FramebufferAttachment *writeBuffer,
38 GLint srcX0,
39 GLint srcY0,
40 GLint srcX1,
41 GLint srcY1,
42 GLint dstX0,
43 GLint dstY0,
44 GLint dstX1,
45 GLint dstY1)
46{
47 const Extents &writeSize = writeBuffer->getSize();
48 const Extents &readSize = readBuffer->getSize();
49
50 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
51 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
52 {
53 return true;
54 }
55
Jamie Madilldfde6ab2016-06-09 07:07:18 -070056 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050057 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070058 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050059 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
60 scissor.height < writeSize.height;
61 }
62
63 return false;
64}
65
Sami Väisänend59ca052016-06-21 16:10:00 +030066template <typename T>
67bool ValidatePathInstances(gl::Context *context,
68 GLsizei numPaths,
69 const void *paths,
70 GLuint pathBase)
71{
72 const auto *array = static_cast<const T *>(paths);
73
74 for (GLsizei i = 0; i < numPaths; ++i)
75 {
76 const GLuint pathName = array[i] + pathBase;
77 if (context->hasPath(pathName) && !context->hasPathData(pathName))
78 {
Brandon Jonesafa75152017-07-21 13:11:29 -070079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030080 return false;
81 }
82 }
83 return true;
84}
85
86bool ValidateInstancedPathParameters(gl::Context *context,
87 GLsizei numPaths,
88 GLenum pathNameType,
89 const void *paths,
90 GLuint pathBase,
91 GLenum transformType,
92 const GLfloat *transformValues)
93{
94 if (!context->getExtensions().pathRendering)
95 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050096 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030097 return false;
98 }
99
100 if (paths == nullptr)
101 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500102 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300103 return false;
104 }
105
106 if (numPaths < 0)
107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500108 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300109 return false;
110 }
111
112 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
113 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700114 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300115 return false;
116 }
117
118 std::uint32_t pathNameTypeSize = 0;
119 std::uint32_t componentCount = 0;
120
121 switch (pathNameType)
122 {
123 case GL_UNSIGNED_BYTE:
124 pathNameTypeSize = sizeof(GLubyte);
125 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
126 return false;
127 break;
128
129 case GL_BYTE:
130 pathNameTypeSize = sizeof(GLbyte);
131 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
132 return false;
133 break;
134
135 case GL_UNSIGNED_SHORT:
136 pathNameTypeSize = sizeof(GLushort);
137 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
138 return false;
139 break;
140
141 case GL_SHORT:
142 pathNameTypeSize = sizeof(GLshort);
143 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
144 return false;
145 break;
146
147 case GL_UNSIGNED_INT:
148 pathNameTypeSize = sizeof(GLuint);
149 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
150 return false;
151 break;
152
153 case GL_INT:
154 pathNameTypeSize = sizeof(GLint);
155 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
156 return false;
157 break;
158
159 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500160 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300161 return false;
162 }
163
164 switch (transformType)
165 {
166 case GL_NONE:
167 componentCount = 0;
168 break;
169 case GL_TRANSLATE_X_CHROMIUM:
170 case GL_TRANSLATE_Y_CHROMIUM:
171 componentCount = 1;
172 break;
173 case GL_TRANSLATE_2D_CHROMIUM:
174 componentCount = 2;
175 break;
176 case GL_TRANSLATE_3D_CHROMIUM:
177 componentCount = 3;
178 break;
179 case GL_AFFINE_2D_CHROMIUM:
180 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
181 componentCount = 6;
182 break;
183 case GL_AFFINE_3D_CHROMIUM:
184 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
185 componentCount = 12;
186 break;
187 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500188 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300189 return false;
190 }
191 if (componentCount != 0 && transformValues == nullptr)
192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500193 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300194 return false;
195 }
196
197 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
198 checkedSize += (numPaths * pathNameTypeSize);
199 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
200 if (!checkedSize.IsValid())
201 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300203 return false;
204 }
205
206 return true;
207}
208
Geoff Lang4f0e0032017-05-01 16:04:35 -0400209bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700210{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400211 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400212 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700213 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700215 case GL_ALPHA:
216 case GL_LUMINANCE:
217 case GL_LUMINANCE_ALPHA:
218 case GL_RGB:
219 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400220 case GL_RGB8:
221 case GL_RGBA8:
222 case GL_BGRA_EXT:
223 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700224 return true;
225
Geoff Lang4f0e0032017-05-01 16:04:35 -0400226 default:
227 return false;
228 }
229}
Geoff Lang97073d12016-04-20 10:42:34 -0700230
Geoff Lang4f0e0032017-05-01 16:04:35 -0400231bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
232{
233 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
234}
235
Geoff Lang4f0e0032017-05-01 16:04:35 -0400236bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
237{
238 // Table 1.0 from the CHROMIUM_copy_texture spec
239 switch (internalFormat)
240 {
241 case GL_RGB:
242 case GL_RGBA:
243 case GL_RGB8:
244 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700245 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400246 case GL_BGRA8_EXT:
247 case GL_SRGB_EXT:
248 case GL_SRGB_ALPHA_EXT:
249 case GL_R8:
250 case GL_R8UI:
251 case GL_RG8:
252 case GL_RG8UI:
253 case GL_SRGB8:
254 case GL_RGB565:
255 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400256 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400257 case GL_SRGB8_ALPHA8:
258 case GL_RGB5_A1:
259 case GL_RGBA4:
260 case GL_RGBA8UI:
261 case GL_RGB9_E5:
262 case GL_R16F:
263 case GL_R32F:
264 case GL_RG16F:
265 case GL_RG32F:
266 case GL_RGB16F:
267 case GL_RGB32F:
268 case GL_RGBA16F:
269 case GL_RGBA32F:
270 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700271 case GL_LUMINANCE:
272 case GL_LUMINANCE_ALPHA:
273 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400274 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700275
276 default:
277 return false;
278 }
279}
280
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400281bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
282{
283 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
284}
285
Geoff Lang97073d12016-04-20 10:42:34 -0700286bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
287{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400288 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700289 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400290 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700291 }
292
Geoff Langc0094ec2017-08-16 14:16:24 -0400293 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
294 {
295 context->handleError(InvalidOperation()
296 << "Invalid combination of type and internalFormat.");
297 return false;
298 }
299
Geoff Lang4f0e0032017-05-01 16:04:35 -0400300 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
301 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700302 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700304 }
305
306 return true;
307}
308
Geoff Lang63458a32017-10-30 15:16:53 -0400309bool IsValidCopyTextureDestinationTargetEnum(Context *context, GLenum target)
Geoff Lang97073d12016-04-20 10:42:34 -0700310{
311 switch (target)
312 {
313 case GL_TEXTURE_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400314 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
315 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
316 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
317 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
318 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
319 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
Geoff Lang63458a32017-10-30 15:16:53 -0400320 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700321
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400322 case GL_TEXTURE_RECTANGLE_ANGLE:
Geoff Lang63458a32017-10-30 15:16:53 -0400323 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700324
325 default:
326 return false;
327 }
328}
329
Geoff Lang63458a32017-10-30 15:16:53 -0400330bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
331{
332 if (IsCubeMapTextureTarget(target))
333 {
334 return textureType == GL_TEXTURE_CUBE_MAP;
335 }
336 else
337 {
338 return textureType == target;
339 }
340}
341
Geoff Lang97073d12016-04-20 10:42:34 -0700342bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
343{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400344 switch (target)
Geoff Lang97073d12016-04-20 10:42:34 -0700345 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 case GL_TEXTURE_2D:
347 return true;
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 case GL_TEXTURE_RECTANGLE_ANGLE:
349 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400350
351 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
352 // supported
353
354 default:
355 return false;
356 }
357}
358
359bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level)
360{
Geoff Lang3847f942017-07-12 11:17:28 -0400361 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 {
363 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700364 }
365
Geoff Lang4f0e0032017-05-01 16:04:35 -0400366 if (level > 0 && context->getClientVersion() < ES_3_0)
367 {
368 return false;
369 }
Geoff Lang97073d12016-04-20 10:42:34 -0700370
Geoff Lang4f0e0032017-05-01 16:04:35 -0400371 return true;
372}
373
374bool IsValidCopyTextureDestinationLevel(Context *context,
375 GLenum target,
376 GLint level,
377 GLsizei width,
378 GLsizei height)
379{
Geoff Lang3847f942017-07-12 11:17:28 -0400380 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400381 {
382 return false;
383 }
384
Geoff Lang4f0e0032017-05-01 16:04:35 -0400385 const Caps &caps = context->getCaps();
386 if (target == GL_TEXTURE_2D)
387 {
388 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
389 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
390 {
391 return false;
392 }
393 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400394 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
395 {
396 ASSERT(level == 0);
397 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
398 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
399 {
400 return false;
401 }
402 }
Geoff Lang4f0e0032017-05-01 16:04:35 -0400403 else if (IsCubeMapTextureTarget(target))
404 {
405 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
406 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
407 {
408 return false;
409 }
410 }
411
412 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700413}
414
Jamie Madillc1d770e2017-04-13 17:31:24 -0400415bool IsValidStencilFunc(GLenum func)
416{
417 switch (func)
418 {
419 case GL_NEVER:
420 case GL_ALWAYS:
421 case GL_LESS:
422 case GL_LEQUAL:
423 case GL_EQUAL:
424 case GL_GEQUAL:
425 case GL_GREATER:
426 case GL_NOTEQUAL:
427 return true;
428
429 default:
430 return false;
431 }
432}
433
434bool IsValidStencilFace(GLenum face)
435{
436 switch (face)
437 {
438 case GL_FRONT:
439 case GL_BACK:
440 case GL_FRONT_AND_BACK:
441 return true;
442
443 default:
444 return false;
445 }
446}
447
448bool IsValidStencilOp(GLenum op)
449{
450 switch (op)
451 {
452 case GL_ZERO:
453 case GL_KEEP:
454 case GL_REPLACE:
455 case GL_INCR:
456 case GL_DECR:
457 case GL_INVERT:
458 case GL_INCR_WRAP:
459 case GL_DECR_WRAP:
460 return true;
461
462 default:
463 return false;
464 }
465}
466
Jamie Madillbe849e42017-05-02 15:49:00 -0400467bool ValidateES2CopyTexImageParameters(ValidationContext *context,
468 GLenum target,
469 GLint level,
470 GLenum internalformat,
471 bool isSubImage,
472 GLint xoffset,
473 GLint yoffset,
474 GLint x,
475 GLint y,
476 GLsizei width,
477 GLsizei height,
478 GLint border)
479{
480 if (!ValidTexture2DDestinationTarget(context, target))
481 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700482 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400483 return false;
484 }
485
486 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
487 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500488 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400489 return false;
490 }
491
492 Format textureFormat = Format::Invalid();
493 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
494 xoffset, yoffset, 0, x, y, width, height, border,
495 &textureFormat))
496 {
497 return false;
498 }
499
500 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
501 GLenum colorbufferFormat =
502 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
503 const auto &formatInfo = *textureFormat.info;
504
505 // [OpenGL ES 2.0.24] table 3.9
506 if (isSubImage)
507 {
508 switch (formatInfo.format)
509 {
510 case GL_ALPHA:
511 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400512 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
513 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400514 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400516 return false;
517 }
518 break;
519 case GL_LUMINANCE:
520 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
521 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
522 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400523 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
524 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400525 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400527 return false;
528 }
529 break;
530 case GL_RED_EXT:
531 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
532 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
533 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
534 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
535 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400536 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
537 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400538 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700539 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400540 return false;
541 }
542 break;
543 case GL_RG_EXT:
544 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
545 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
546 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
547 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400548 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
549 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400550 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400552 return false;
553 }
554 break;
555 case GL_RGB:
556 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
557 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
558 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400559 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
560 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400561 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700562 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400563 return false;
564 }
565 break;
566 case GL_LUMINANCE_ALPHA:
567 case GL_RGBA:
568 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400569 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
570 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400571 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700572 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400573 return false;
574 }
575 break;
576 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
577 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
578 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
579 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
580 case GL_ETC1_RGB8_OES:
581 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
582 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
583 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
584 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
585 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700586 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400587 return false;
588 case GL_DEPTH_COMPONENT:
589 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700590 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700593 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400594 return false;
595 }
596
597 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
598 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700599 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400600 return false;
601 }
602 }
603 else
604 {
605 switch (internalformat)
606 {
607 case GL_ALPHA:
608 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
609 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
610 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
611 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700612 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400613 return false;
614 }
615 break;
616 case GL_LUMINANCE:
617 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
618 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
619 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
620 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
621 colorbufferFormat != GL_BGR5_A1_ANGLEX)
622 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400624 return false;
625 }
626 break;
627 case GL_RED_EXT:
628 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
629 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
630 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
631 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
632 colorbufferFormat != GL_BGR5_A1_ANGLEX)
633 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700634 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400635 return false;
636 }
637 break;
638 case GL_RG_EXT:
639 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
640 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
641 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
642 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
643 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700644 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400645 return false;
646 }
647 break;
648 case GL_RGB:
649 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
650 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
651 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
652 colorbufferFormat != GL_BGR5_A1_ANGLEX)
653 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700654 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400655 return false;
656 }
657 break;
658 case GL_LUMINANCE_ALPHA:
659 case GL_RGBA:
660 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
661 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
662 colorbufferFormat != GL_BGR5_A1_ANGLEX)
663 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700664 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400665 return false;
666 }
667 break;
668 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
669 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
670 if (context->getExtensions().textureCompressionDXT1)
671 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700672 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400673 return false;
674 }
675 else
676 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700677 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400678 return false;
679 }
680 break;
681 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
682 if (context->getExtensions().textureCompressionDXT3)
683 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700684 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400685 return false;
686 }
687 else
688 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700689 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400690 return false;
691 }
692 break;
693 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
694 if (context->getExtensions().textureCompressionDXT5)
695 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700696 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400697 return false;
698 }
699 else
700 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700701 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400702 return false;
703 }
704 break;
705 case GL_ETC1_RGB8_OES:
706 if (context->getExtensions().compressedETC1RGB8Texture)
707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500708 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400709 return false;
710 }
711 else
712 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500713 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400714 return false;
715 }
716 break;
717 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
718 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
719 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
720 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
721 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
722 if (context->getExtensions().lossyETCDecode)
723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500724 context->handleError(InvalidOperation()
725 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400726 return false;
727 }
728 else
729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500730 context->handleError(InvalidEnum()
731 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400732 return false;
733 }
734 break;
735 case GL_DEPTH_COMPONENT:
736 case GL_DEPTH_COMPONENT16:
737 case GL_DEPTH_COMPONENT32_OES:
738 case GL_DEPTH_STENCIL_OES:
739 case GL_DEPTH24_STENCIL8_OES:
740 if (context->getExtensions().depthTextures)
741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500742 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 else
746 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500747 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400748 return false;
749 }
750 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500751 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400752 return false;
753 }
754 }
755
756 // If width or height is zero, it is a no-op. Return false without setting an error.
757 return (width > 0 && height > 0);
758}
759
760bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
761{
762 switch (cap)
763 {
764 // EXT_multisample_compatibility
765 case GL_MULTISAMPLE_EXT:
766 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
767 return context->getExtensions().multisampleCompatibility;
768
769 case GL_CULL_FACE:
770 case GL_POLYGON_OFFSET_FILL:
771 case GL_SAMPLE_ALPHA_TO_COVERAGE:
772 case GL_SAMPLE_COVERAGE:
773 case GL_SCISSOR_TEST:
774 case GL_STENCIL_TEST:
775 case GL_DEPTH_TEST:
776 case GL_BLEND:
777 case GL_DITHER:
778 return true;
779
780 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
781 case GL_RASTERIZER_DISCARD:
782 return (context->getClientMajorVersion() >= 3);
783
784 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
785 case GL_DEBUG_OUTPUT:
786 return context->getExtensions().debug;
787
788 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
789 return queryOnly && context->getExtensions().bindGeneratesResource;
790
791 case GL_CLIENT_ARRAYS_ANGLE:
792 return queryOnly && context->getExtensions().clientArrays;
793
794 case GL_FRAMEBUFFER_SRGB_EXT:
795 return context->getExtensions().sRGBWriteControl;
796
797 case GL_SAMPLE_MASK:
798 return context->getClientVersion() >= Version(3, 1);
799
Geoff Langb433e872017-10-05 14:01:47 -0400800 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400801 return queryOnly && context->getExtensions().robustResourceInitialization;
802
803 default:
804 return false;
805 }
806}
807
Geoff Langfc32e8b2017-05-31 14:16:59 -0400808// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
809// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400810bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400811{
812 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400813 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
814 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400815 {
816 return true;
817 }
818
819 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
820 if (c >= 9 && c <= 13)
821 {
822 return true;
823 }
824
825 return false;
826}
827
Geoff Langcab92ee2017-07-19 17:32:07 -0400828bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400829{
Geoff Langa71a98e2017-06-19 15:15:00 -0400830 for (size_t i = 0; i < len; i++)
831 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400832 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400833 {
834 return false;
835 }
836 }
837
838 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400839}
840
Geoff Langcab92ee2017-07-19 17:32:07 -0400841bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
842{
843 enum class ParseState
844 {
845 // Have not seen an ASCII non-whitespace character yet on
846 // this line. Possible that we might see a preprocessor
847 // directive.
848 BEGINING_OF_LINE,
849
850 // Have seen at least one ASCII non-whitespace character
851 // on this line.
852 MIDDLE_OF_LINE,
853
854 // Handling a preprocessor directive. Passes through all
855 // characters up to the end of the line. Disables comment
856 // processing.
857 IN_PREPROCESSOR_DIRECTIVE,
858
859 // Handling a single-line comment. The comment text is
860 // replaced with a single space.
861 IN_SINGLE_LINE_COMMENT,
862
863 // Handling a multi-line comment. Newlines are passed
864 // through to preserve line numbers.
865 IN_MULTI_LINE_COMMENT
866 };
867
868 ParseState state = ParseState::BEGINING_OF_LINE;
869 size_t pos = 0;
870
871 while (pos < len)
872 {
873 char c = str[pos];
874 char next = pos + 1 < len ? str[pos + 1] : 0;
875
876 // Check for newlines
877 if (c == '\n' || c == '\r')
878 {
879 if (state != ParseState::IN_MULTI_LINE_COMMENT)
880 {
881 state = ParseState::BEGINING_OF_LINE;
882 }
883
884 pos++;
885 continue;
886 }
887
888 switch (state)
889 {
890 case ParseState::BEGINING_OF_LINE:
891 if (c == ' ')
892 {
893 // Maintain the BEGINING_OF_LINE state until a non-space is seen
894 pos++;
895 }
896 else if (c == '#')
897 {
898 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
899 pos++;
900 }
901 else
902 {
903 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
904 state = ParseState::MIDDLE_OF_LINE;
905 }
906 break;
907
908 case ParseState::MIDDLE_OF_LINE:
909 if (c == '/' && next == '/')
910 {
911 state = ParseState::IN_SINGLE_LINE_COMMENT;
912 pos++;
913 }
914 else if (c == '/' && next == '*')
915 {
916 state = ParseState::IN_MULTI_LINE_COMMENT;
917 pos++;
918 }
919 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
920 {
921 // Skip line continuation characters
922 }
923 else if (!IsValidESSLCharacter(c))
924 {
925 return false;
926 }
927 pos++;
928 break;
929
930 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700931 // Line-continuation characters may not be permitted.
932 // Otherwise, just pass it through. Do not parse comments in this state.
933 if (!lineContinuationAllowed && c == '\\')
934 {
935 return false;
936 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400937 pos++;
938 break;
939
940 case ParseState::IN_SINGLE_LINE_COMMENT:
941 // Line-continuation characters are processed before comment processing.
942 // Advance string if a new line character is immediately behind
943 // line-continuation character.
944 if (c == '\\' && (next == '\n' || next == '\r'))
945 {
946 pos++;
947 }
948 pos++;
949 break;
950
951 case ParseState::IN_MULTI_LINE_COMMENT:
952 if (c == '*' && next == '/')
953 {
954 state = ParseState::MIDDLE_OF_LINE;
955 pos++;
956 }
957 pos++;
958 break;
959 }
960 }
961
962 return true;
963}
964
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700965bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
966{
967 ASSERT(context->isWebGL());
968
969 // WebGL 1.0 [Section 6.16] GLSL Constructs
970 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
971 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
972 {
973 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
974 return false;
975 }
976
977 return true;
978}
979
980bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
981{
982 ASSERT(context->isWebGL());
983
984 if (context->isWebGL1() && length > 256)
985 {
986 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
987 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
988 // locations.
989 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
990
991 return false;
992 }
993 else if (length > 1024)
994 {
995 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
996 // uniform and attribute locations.
997 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
998 return false;
999 }
1000
1001 return true;
1002}
1003
Jamie Madillc29968b2016-01-20 11:17:23 -05001004} // anonymous namespace
1005
Geoff Langff5b2d52016-09-07 11:32:23 -04001006bool ValidateES2TexImageParameters(Context *context,
1007 GLenum target,
1008 GLint level,
1009 GLenum internalformat,
1010 bool isCompressed,
1011 bool isSubImage,
1012 GLint xoffset,
1013 GLint yoffset,
1014 GLsizei width,
1015 GLsizei height,
1016 GLint border,
1017 GLenum format,
1018 GLenum type,
1019 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001020 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001021{
Jamie Madill6f38f822014-06-06 17:12:20 -04001022 if (!ValidTexture2DDestinationTarget(context, target))
1023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001024 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001025 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001026 }
1027
Austin Kinross08528e12015-10-07 16:24:40 -07001028 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001029 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001030 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001031 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001032 }
1033
Brandon Jones6cad5662017-06-14 13:25:13 -07001034 if (!ValidMipLevel(context, target, level))
1035 {
1036 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1037 return false;
1038 }
1039
1040 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001041 std::numeric_limits<GLsizei>::max() - yoffset < height)
1042 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001043 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001044 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001045 }
1046
Geoff Lang6e898aa2017-06-02 11:17:26 -04001047 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1048 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1049 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1050 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1051 // case.
1052 bool nonEqualFormatsAllowed =
1053 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1054 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1055
1056 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001058 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001059 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001060 }
1061
Geoff Langaae65a42014-05-26 12:43:44 -04001062 const gl::Caps &caps = context->getCaps();
1063
Geoff Langa9be0dc2014-12-17 12:34:40 -05001064 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001065 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05001066 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1067 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001068 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001069 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001070 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001071 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001072 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001073 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
1074 {
1075 ASSERT(level == 0);
1076 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1077 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1078 {
1079 context->handleError(InvalidValue());
1080 return false;
1081 }
1082 if (isCompressed)
1083 {
1084 context->handleError(InvalidEnum()
1085 << "Rectangle texture cannot have a compressed format.");
1086 return false;
1087 }
1088 }
Geoff Lang691e58c2014-12-19 17:03:25 -05001089 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -05001090 {
1091 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001092 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001093 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001094 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001095 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001096
Geoff Langa9be0dc2014-12-17 12:34:40 -05001097 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1098 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001100 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001101 return false;
1102 }
1103 }
1104 else
1105 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001106 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001107 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001108 }
1109
He Yunchaoced53ae2016-11-29 15:00:51 +08001110 gl::Texture *texture =
1111 context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001112 if (!texture)
1113 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001114 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001115 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001116 }
1117
Geoff Langa9be0dc2014-12-17 12:34:40 -05001118 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001119 {
Geoff Langca271392017-04-05 12:30:00 -04001120 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1121 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001123 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001124 return false;
1125 }
1126
Geoff Langa9be0dc2014-12-17 12:34:40 -05001127 if (format != GL_NONE)
1128 {
Geoff Langca271392017-04-05 12:30:00 -04001129 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1130 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001131 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001132 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001133 return false;
1134 }
1135 }
1136
1137 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1138 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1139 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001140 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001141 return false;
1142 }
Geoff Langfb052642017-10-24 13:42:09 -04001143
1144 if (width > 0 && height > 0 && pixels == nullptr &&
1145 context->getGLState().getTargetBuffer(GL_PIXEL_UNPACK_BUFFER) == nullptr)
1146 {
1147 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1148 return false;
1149 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001150 }
1151 else
1152 {
Geoff Lang69cce582015-09-17 13:20:36 -04001153 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001155 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001156 return false;
1157 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001158 }
1159
1160 // Verify zero border
1161 if (border != 0)
1162 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001163 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001164 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 }
1166
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 if (isCompressed)
1168 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001169 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001170 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1171 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001172 switch (actualInternalFormat)
1173 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001174 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1175 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1176 if (!context->getExtensions().textureCompressionDXT1)
1177 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001178 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001179 return false;
1180 }
1181 break;
1182 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001183 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001184 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001185 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 return false;
1187 }
1188 break;
1189 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1190 if (!context->getExtensions().textureCompressionDXT5)
1191 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001192 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001193 return false;
1194 }
1195 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001196 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1197 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1198 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1199 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1200 if (!context->getExtensions().textureCompressionS3TCsRGB)
1201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001202 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001203 return false;
1204 }
1205 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001206 case GL_ETC1_RGB8_OES:
1207 if (!context->getExtensions().compressedETC1RGB8Texture)
1208 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001209 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001210 return false;
1211 }
Geoff Lang86f81162017-10-30 15:10:45 -04001212 if (isSubImage)
1213 {
1214 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1215 return false;
1216 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001217 break;
1218 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001219 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1220 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1221 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1222 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001223 if (!context->getExtensions().lossyETCDecode)
1224 {
Geoff Lang86f81162017-10-30 15:10:45 -04001225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001226 return false;
1227 }
1228 break;
1229 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001230 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001231 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001232 }
Geoff Lang966c9402017-04-18 12:38:27 -04001233
1234 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001235 {
Geoff Lang966c9402017-04-18 12:38:27 -04001236 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1237 height, texture->getWidth(target, level),
1238 texture->getHeight(target, level)))
1239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001240 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001241 return false;
1242 }
1243
1244 if (format != actualInternalFormat)
1245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001247 return false;
1248 }
1249 }
1250 else
1251 {
1252 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001254 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001255 return false;
1256 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001257 }
1258 }
1259 else
1260 {
1261 // validate <type> by itself (used as secondary key below)
1262 switch (type)
1263 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001264 case GL_UNSIGNED_BYTE:
1265 case GL_UNSIGNED_SHORT_5_6_5:
1266 case GL_UNSIGNED_SHORT_4_4_4_4:
1267 case GL_UNSIGNED_SHORT_5_5_5_1:
1268 case GL_UNSIGNED_SHORT:
1269 case GL_UNSIGNED_INT:
1270 case GL_UNSIGNED_INT_24_8_OES:
1271 case GL_HALF_FLOAT_OES:
1272 case GL_FLOAT:
1273 break;
1274 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001275 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001276 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001277 }
1278
1279 // validate <format> + <type> combinations
1280 // - invalid <format> -> sets INVALID_ENUM
1281 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1282 switch (format)
1283 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001284 case GL_ALPHA:
1285 case GL_LUMINANCE:
1286 case GL_LUMINANCE_ALPHA:
1287 switch (type)
1288 {
1289 case GL_UNSIGNED_BYTE:
1290 case GL_FLOAT:
1291 case GL_HALF_FLOAT_OES:
1292 break;
1293 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001294 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001295 return false;
1296 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001297 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001298 case GL_RED:
1299 case GL_RG:
1300 if (!context->getExtensions().textureRG)
1301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001302 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001303 return false;
1304 }
1305 switch (type)
1306 {
1307 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001308 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001309 case GL_FLOAT:
1310 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001311 if (!context->getExtensions().textureFloat)
1312 {
1313 context->handleError(InvalidEnum());
1314 return false;
1315 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001316 break;
1317 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001319 return false;
1320 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001321 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001322 case GL_RGB:
1323 switch (type)
1324 {
1325 case GL_UNSIGNED_BYTE:
1326 case GL_UNSIGNED_SHORT_5_6_5:
1327 case GL_FLOAT:
1328 case GL_HALF_FLOAT_OES:
1329 break;
1330 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001331 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001332 return false;
1333 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001334 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 case GL_RGBA:
1336 switch (type)
1337 {
1338 case GL_UNSIGNED_BYTE:
1339 case GL_UNSIGNED_SHORT_4_4_4_4:
1340 case GL_UNSIGNED_SHORT_5_5_5_1:
1341 case GL_FLOAT:
1342 case GL_HALF_FLOAT_OES:
1343 break;
1344 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001346 return false;
1347 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001348 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001349 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001350 if (!context->getExtensions().textureFormatBGRA8888)
1351 {
1352 context->handleError(InvalidEnum());
1353 return false;
1354 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 break;
1359 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001360 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001361 return false;
1362 }
1363 break;
1364 case GL_SRGB_EXT:
1365 case GL_SRGB_ALPHA_EXT:
1366 if (!context->getExtensions().sRGB)
1367 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001368 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 switch (type)
1372 {
1373 case GL_UNSIGNED_BYTE:
1374 break;
1375 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001377 return false;
1378 }
1379 break;
1380 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1381 // handled below
1382 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1383 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1384 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1385 break;
1386 case GL_DEPTH_COMPONENT:
1387 switch (type)
1388 {
1389 case GL_UNSIGNED_SHORT:
1390 case GL_UNSIGNED_INT:
1391 break;
1392 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001394 return false;
1395 }
1396 break;
1397 case GL_DEPTH_STENCIL_OES:
1398 switch (type)
1399 {
1400 case GL_UNSIGNED_INT_24_8_OES:
1401 break;
1402 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001404 return false;
1405 }
1406 break;
1407 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001408 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001409 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001410 }
1411
1412 switch (format)
1413 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001414 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1415 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1416 if (context->getExtensions().textureCompressionDXT1)
1417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001418 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001419 return false;
1420 }
1421 else
1422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001423 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001424 return false;
1425 }
1426 break;
1427 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1428 if (context->getExtensions().textureCompressionDXT3)
1429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001430 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 return false;
1432 }
1433 else
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1440 if (context->getExtensions().textureCompressionDXT5)
1441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001442 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 else
1446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001447 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001448 return false;
1449 }
1450 break;
1451 case GL_ETC1_RGB8_OES:
1452 if (context->getExtensions().compressedETC1RGB8Texture)
1453 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001454 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
1457 else
1458 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001459 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001460 return false;
1461 }
1462 break;
1463 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001464 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1465 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1466 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1467 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 if (context->getExtensions().lossyETCDecode)
1469 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001470 context->handleError(InvalidOperation()
1471 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 return false;
1473 }
1474 else
1475 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001476 context->handleError(InvalidEnum()
1477 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 return false;
1479 }
1480 break;
1481 case GL_DEPTH_COMPONENT:
1482 case GL_DEPTH_STENCIL_OES:
1483 if (!context->getExtensions().depthTextures)
1484 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001485 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001486 return false;
1487 }
1488 if (target != GL_TEXTURE_2D)
1489 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001490 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 return false;
1492 }
1493 // OES_depth_texture supports loading depth data and multiple levels,
1494 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001495 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001496 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001497 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1498 return false;
1499 }
1500 if (level != 0)
1501 {
1502 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 break;
1506 default:
1507 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001508 }
1509
Geoff Lang6e898aa2017-06-02 11:17:26 -04001510 if (!isSubImage)
1511 {
1512 switch (internalformat)
1513 {
1514 case GL_RGBA32F:
1515 if (!context->getExtensions().colorBufferFloatRGBA)
1516 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001517 context->handleError(InvalidValue()
1518 << "Sized GL_RGBA32F internal format requires "
1519 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001520 return false;
1521 }
1522 if (type != GL_FLOAT)
1523 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001524 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001525 return false;
1526 }
1527 if (format != GL_RGBA)
1528 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001529 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001530 return false;
1531 }
1532 break;
1533
1534 case GL_RGB32F:
1535 if (!context->getExtensions().colorBufferFloatRGB)
1536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001537 context->handleError(InvalidValue()
1538 << "Sized GL_RGB32F internal format requires "
1539 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001540 return false;
1541 }
1542 if (type != GL_FLOAT)
1543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001545 return false;
1546 }
1547 if (format != GL_RGB)
1548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001550 return false;
1551 }
1552 break;
1553
1554 default:
1555 break;
1556 }
1557 }
1558
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001559 if (type == GL_FLOAT)
1560 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001561 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001562 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001563 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001564 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001565 }
1566 }
1567 else if (type == GL_HALF_FLOAT_OES)
1568 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001569 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001572 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001573 }
1574 }
1575 }
1576
Geoff Langdbcced82017-06-06 15:55:54 -04001577 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1578 if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001579 imageSize))
1580 {
1581 return false;
1582 }
1583
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001584 return true;
1585}
1586
He Yunchaoced53ae2016-11-29 15:00:51 +08001587bool ValidateES2TexStorageParameters(Context *context,
1588 GLenum target,
1589 GLsizei levels,
1590 GLenum internalformat,
1591 GLsizei width,
1592 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593{
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001594 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
1595 target != GL_TEXTURE_RECTANGLE_ANGLE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001596 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001597 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001598 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001599 }
1600
1601 if (width < 1 || height < 1 || levels < 1)
1602 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001603 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001604 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001605 }
1606
1607 if (target == GL_TEXTURE_CUBE_MAP && width != height)
1608 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001609 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001610 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001611 }
1612
1613 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1614 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001615 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001616 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001617 }
1618
Geoff Langca271392017-04-05 12:30:00 -04001619 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001620 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001621 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001622 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001623 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001624 }
1625
Geoff Langaae65a42014-05-26 12:43:44 -04001626 const gl::Caps &caps = context->getCaps();
1627
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 switch (target)
1629 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001630 case GL_TEXTURE_2D:
1631 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1632 static_cast<GLuint>(height) > caps.max2DTextureSize)
1633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001635 return false;
1636 }
1637 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001638 case GL_TEXTURE_RECTANGLE_ANGLE:
1639 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1640 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1641 {
1642 context->handleError(InvalidValue());
1643 return false;
1644 }
1645 if (formatInfo.compressed)
1646 {
1647 context->handleError(InvalidEnum()
1648 << "Rectangle texture cannot have a compressed format.");
1649 return false;
1650 }
1651 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001652 case GL_TEXTURE_CUBE_MAP:
1653 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1654 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1655 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001656 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001657 return false;
1658 }
1659 break;
1660 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001661 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001662 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001663 }
1664
Geoff Langc0b9ef42014-07-02 10:02:37 -04001665 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001666 {
1667 if (!gl::isPow2(width) || !gl::isPow2(height))
1668 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001669 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001670 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 }
1672 }
1673
1674 switch (internalformat)
1675 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001676 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1677 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1678 if (!context->getExtensions().textureCompressionDXT1)
1679 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001680 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001681 return false;
1682 }
1683 break;
1684 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1685 if (!context->getExtensions().textureCompressionDXT3)
1686 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001687 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001688 return false;
1689 }
1690 break;
1691 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1692 if (!context->getExtensions().textureCompressionDXT5)
1693 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001694 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001695 return false;
1696 }
1697 break;
1698 case GL_ETC1_RGB8_OES:
1699 if (!context->getExtensions().compressedETC1RGB8Texture)
1700 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001701 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001702 return false;
1703 }
1704 break;
1705 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001706 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1707 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1708 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1709 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001710 if (!context->getExtensions().lossyETCDecode)
1711 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001712 context->handleError(InvalidEnum()
1713 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001714 return false;
1715 }
1716 break;
1717 case GL_RGBA32F_EXT:
1718 case GL_RGB32F_EXT:
1719 case GL_ALPHA32F_EXT:
1720 case GL_LUMINANCE32F_EXT:
1721 case GL_LUMINANCE_ALPHA32F_EXT:
1722 if (!context->getExtensions().textureFloat)
1723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001725 return false;
1726 }
1727 break;
1728 case GL_RGBA16F_EXT:
1729 case GL_RGB16F_EXT:
1730 case GL_ALPHA16F_EXT:
1731 case GL_LUMINANCE16F_EXT:
1732 case GL_LUMINANCE_ALPHA16F_EXT:
1733 if (!context->getExtensions().textureHalfFloat)
1734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001735 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001736 return false;
1737 }
1738 break;
1739 case GL_R8_EXT:
1740 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001741 if (!context->getExtensions().textureRG)
1742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001743 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001744 return false;
1745 }
1746 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 case GL_R16F_EXT:
1748 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001749 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001751 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001752 return false;
1753 }
1754 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001755 case GL_R32F_EXT:
1756 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001757 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001758 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001759 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001760 return false;
1761 }
1762 break;
1763 case GL_DEPTH_COMPONENT16:
1764 case GL_DEPTH_COMPONENT32_OES:
1765 case GL_DEPTH24_STENCIL8_OES:
1766 if (!context->getExtensions().depthTextures)
1767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 if (target != GL_TEXTURE_2D)
1772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001773 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 return false;
1775 }
1776 // ANGLE_depth_texture only supports 1-level textures
1777 if (levels != 1)
1778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001779 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001780 return false;
1781 }
1782 break;
1783 default:
1784 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001785 }
1786
Geoff Lang691e58c2014-12-19 17:03:25 -05001787 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001788 if (!texture || texture->id() == 0)
1789 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001790 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001791 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001792 }
1793
Geoff Lang69cce582015-09-17 13:20:36 -04001794 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001796 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001797 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001798 }
1799
1800 return true;
1801}
1802
He Yunchaoced53ae2016-11-29 15:00:51 +08001803bool ValidateDiscardFramebufferEXT(Context *context,
1804 GLenum target,
1805 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001806 const GLenum *attachments)
1807{
Jamie Madillc29968b2016-01-20 11:17:23 -05001808 if (!context->getExtensions().discardFramebuffer)
1809 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001810 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001811 return false;
1812 }
1813
Austin Kinross08332632015-05-05 13:35:47 -07001814 bool defaultFramebuffer = false;
1815
1816 switch (target)
1817 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001818 case GL_FRAMEBUFFER:
1819 defaultFramebuffer =
1820 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1821 break;
1822 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001823 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001824 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001825 }
1826
He Yunchaoced53ae2016-11-29 15:00:51 +08001827 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1828 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001829}
1830
Austin Kinrossbc781f32015-10-26 09:27:38 -07001831bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1832{
1833 if (!context->getExtensions().vertexArrayObject)
1834 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001835 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001836 return false;
1837 }
1838
1839 return ValidateBindVertexArrayBase(context, array);
1840}
1841
Jamie Madilld7576732017-08-26 18:49:50 -04001842bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001843{
1844 if (!context->getExtensions().vertexArrayObject)
1845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001846 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001847 return false;
1848 }
1849
Olli Etuaho41997e72016-03-10 13:38:39 +02001850 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001851}
1852
Jamie Madilld7576732017-08-26 18:49:50 -04001853bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001854{
1855 if (!context->getExtensions().vertexArrayObject)
1856 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001857 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001858 return false;
1859 }
1860
Olli Etuaho41997e72016-03-10 13:38:39 +02001861 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001862}
1863
Jamie Madilld7576732017-08-26 18:49:50 -04001864bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001865{
1866 if (!context->getExtensions().vertexArrayObject)
1867 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001868 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001869 return false;
1870 }
1871
1872 return true;
1873}
Geoff Langc5629752015-12-07 16:29:04 -05001874
1875bool ValidateProgramBinaryOES(Context *context,
1876 GLuint program,
1877 GLenum binaryFormat,
1878 const void *binary,
1879 GLint length)
1880{
1881 if (!context->getExtensions().getProgramBinary)
1882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001883 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001884 return false;
1885 }
1886
1887 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1888}
1889
1890bool ValidateGetProgramBinaryOES(Context *context,
1891 GLuint program,
1892 GLsizei bufSize,
1893 GLsizei *length,
1894 GLenum *binaryFormat,
1895 void *binary)
1896{
1897 if (!context->getExtensions().getProgramBinary)
1898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001899 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001900 return false;
1901 }
1902
1903 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1904}
Geoff Lange102fee2015-12-10 11:23:30 -05001905
Geoff Lang70d0f492015-12-10 17:45:46 -05001906static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1907{
1908 switch (source)
1909 {
1910 case GL_DEBUG_SOURCE_API:
1911 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1912 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1913 case GL_DEBUG_SOURCE_OTHER:
1914 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1915 return !mustBeThirdPartyOrApplication;
1916
1917 case GL_DEBUG_SOURCE_THIRD_PARTY:
1918 case GL_DEBUG_SOURCE_APPLICATION:
1919 return true;
1920
1921 default:
1922 return false;
1923 }
1924}
1925
1926static bool ValidDebugType(GLenum type)
1927{
1928 switch (type)
1929 {
1930 case GL_DEBUG_TYPE_ERROR:
1931 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1932 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1933 case GL_DEBUG_TYPE_PERFORMANCE:
1934 case GL_DEBUG_TYPE_PORTABILITY:
1935 case GL_DEBUG_TYPE_OTHER:
1936 case GL_DEBUG_TYPE_MARKER:
1937 case GL_DEBUG_TYPE_PUSH_GROUP:
1938 case GL_DEBUG_TYPE_POP_GROUP:
1939 return true;
1940
1941 default:
1942 return false;
1943 }
1944}
1945
1946static bool ValidDebugSeverity(GLenum severity)
1947{
1948 switch (severity)
1949 {
1950 case GL_DEBUG_SEVERITY_HIGH:
1951 case GL_DEBUG_SEVERITY_MEDIUM:
1952 case GL_DEBUG_SEVERITY_LOW:
1953 case GL_DEBUG_SEVERITY_NOTIFICATION:
1954 return true;
1955
1956 default:
1957 return false;
1958 }
1959}
1960
Geoff Lange102fee2015-12-10 11:23:30 -05001961bool ValidateDebugMessageControlKHR(Context *context,
1962 GLenum source,
1963 GLenum type,
1964 GLenum severity,
1965 GLsizei count,
1966 const GLuint *ids,
1967 GLboolean enabled)
1968{
1969 if (!context->getExtensions().debug)
1970 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001971 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001972 return false;
1973 }
1974
Geoff Lang70d0f492015-12-10 17:45:46 -05001975 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1976 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001977 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001978 return false;
1979 }
1980
1981 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1982 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001983 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001984 return false;
1985 }
1986
1987 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1988 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001989 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001990 return false;
1991 }
1992
1993 if (count > 0)
1994 {
1995 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001997 context->handleError(
1998 InvalidOperation()
1999 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002000 return false;
2001 }
2002
2003 if (severity != GL_DONT_CARE)
2004 {
Jamie Madill437fa652016-05-03 15:13:24 -04002005 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002006 InvalidOperation()
2007 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002008 return false;
2009 }
2010 }
2011
Geoff Lange102fee2015-12-10 11:23:30 -05002012 return true;
2013}
2014
2015bool ValidateDebugMessageInsertKHR(Context *context,
2016 GLenum source,
2017 GLenum type,
2018 GLuint id,
2019 GLenum severity,
2020 GLsizei length,
2021 const GLchar *buf)
2022{
2023 if (!context->getExtensions().debug)
2024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002025 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002026 return false;
2027 }
2028
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002029 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002030 {
2031 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2032 // not generate an error.
2033 return false;
2034 }
2035
2036 if (!ValidDebugSeverity(severity))
2037 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002038 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002039 return false;
2040 }
2041
2042 if (!ValidDebugType(type))
2043 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002044 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002045 return false;
2046 }
2047
2048 if (!ValidDebugSource(source, true))
2049 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002051 return false;
2052 }
2053
2054 size_t messageLength = (length < 0) ? strlen(buf) : length;
2055 if (messageLength > context->getExtensions().maxDebugMessageLength)
2056 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002057 context->handleError(InvalidValue()
2058 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 return false;
2060 }
2061
Geoff Lange102fee2015-12-10 11:23:30 -05002062 return true;
2063}
2064
2065bool ValidateDebugMessageCallbackKHR(Context *context,
2066 GLDEBUGPROCKHR callback,
2067 const void *userParam)
2068{
2069 if (!context->getExtensions().debug)
2070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002071 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002072 return false;
2073 }
2074
Geoff Lange102fee2015-12-10 11:23:30 -05002075 return true;
2076}
2077
2078bool ValidateGetDebugMessageLogKHR(Context *context,
2079 GLuint count,
2080 GLsizei bufSize,
2081 GLenum *sources,
2082 GLenum *types,
2083 GLuint *ids,
2084 GLenum *severities,
2085 GLsizei *lengths,
2086 GLchar *messageLog)
2087{
2088 if (!context->getExtensions().debug)
2089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002090 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002091 return false;
2092 }
2093
Geoff Lang70d0f492015-12-10 17:45:46 -05002094 if (bufSize < 0 && messageLog != nullptr)
2095 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002096 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002097 return false;
2098 }
2099
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return true;
2101}
2102
2103bool ValidatePushDebugGroupKHR(Context *context,
2104 GLenum source,
2105 GLuint id,
2106 GLsizei length,
2107 const GLchar *message)
2108{
2109 if (!context->getExtensions().debug)
2110 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002111 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002112 return false;
2113 }
2114
Geoff Lang70d0f492015-12-10 17:45:46 -05002115 if (!ValidDebugSource(source, true))
2116 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 size_t messageLength = (length < 0) ? strlen(message) : length;
2122 if (messageLength > context->getExtensions().maxDebugMessageLength)
2123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002124 context->handleError(InvalidValue()
2125 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002129 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002130 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002132 context
2133 ->handleError(StackOverflow()
2134 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002135 return false;
2136 }
2137
Geoff Lange102fee2015-12-10 11:23:30 -05002138 return true;
2139}
2140
2141bool ValidatePopDebugGroupKHR(Context *context)
2142{
2143 if (!context->getExtensions().debug)
2144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002146 return false;
2147 }
2148
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002149 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002150 if (currentStackSize <= 1)
2151 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002152 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002153 return false;
2154 }
2155
2156 return true;
2157}
2158
2159static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2160{
2161 switch (identifier)
2162 {
2163 case GL_BUFFER:
2164 if (context->getBuffer(name) == nullptr)
2165 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002166 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002167 return false;
2168 }
2169 return true;
2170
2171 case GL_SHADER:
2172 if (context->getShader(name) == nullptr)
2173 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002174 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002175 return false;
2176 }
2177 return true;
2178
2179 case GL_PROGRAM:
2180 if (context->getProgram(name) == nullptr)
2181 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002182 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002183 return false;
2184 }
2185 return true;
2186
2187 case GL_VERTEX_ARRAY:
2188 if (context->getVertexArray(name) == nullptr)
2189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002190 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002191 return false;
2192 }
2193 return true;
2194
2195 case GL_QUERY:
2196 if (context->getQuery(name) == nullptr)
2197 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002198 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 return false;
2200 }
2201 return true;
2202
2203 case GL_TRANSFORM_FEEDBACK:
2204 if (context->getTransformFeedback(name) == nullptr)
2205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002206 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002207 return false;
2208 }
2209 return true;
2210
2211 case GL_SAMPLER:
2212 if (context->getSampler(name) == nullptr)
2213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002214 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002215 return false;
2216 }
2217 return true;
2218
2219 case GL_TEXTURE:
2220 if (context->getTexture(name) == nullptr)
2221 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002222 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002223 return false;
2224 }
2225 return true;
2226
2227 case GL_RENDERBUFFER:
2228 if (context->getRenderbuffer(name) == nullptr)
2229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002230 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 return false;
2232 }
2233 return true;
2234
2235 case GL_FRAMEBUFFER:
2236 if (context->getFramebuffer(name) == nullptr)
2237 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002238 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002239 return false;
2240 }
2241 return true;
2242
2243 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002244 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002245 return false;
2246 }
Geoff Lange102fee2015-12-10 11:23:30 -05002247}
2248
Martin Radev9d901792016-07-15 15:58:58 +03002249static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2250{
2251 size_t labelLength = 0;
2252
2253 if (length < 0)
2254 {
2255 if (label != nullptr)
2256 {
2257 labelLength = strlen(label);
2258 }
2259 }
2260 else
2261 {
2262 labelLength = static_cast<size_t>(length);
2263 }
2264
2265 if (labelLength > context->getExtensions().maxLabelLength)
2266 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002267 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002268 return false;
2269 }
2270
2271 return true;
2272}
2273
Geoff Lange102fee2015-12-10 11:23:30 -05002274bool ValidateObjectLabelKHR(Context *context,
2275 GLenum identifier,
2276 GLuint name,
2277 GLsizei length,
2278 const GLchar *label)
2279{
2280 if (!context->getExtensions().debug)
2281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002282 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002283 return false;
2284 }
2285
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2287 {
2288 return false;
2289 }
2290
Martin Radev9d901792016-07-15 15:58:58 +03002291 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002292 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 return false;
2294 }
2295
Geoff Lange102fee2015-12-10 11:23:30 -05002296 return true;
2297}
2298
2299bool ValidateGetObjectLabelKHR(Context *context,
2300 GLenum identifier,
2301 GLuint name,
2302 GLsizei bufSize,
2303 GLsizei *length,
2304 GLchar *label)
2305{
2306 if (!context->getExtensions().debug)
2307 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002308 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002309 return false;
2310 }
2311
Geoff Lang70d0f492015-12-10 17:45:46 -05002312 if (bufSize < 0)
2313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002314 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 return false;
2316 }
2317
2318 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2319 {
2320 return false;
2321 }
2322
Martin Radev9d901792016-07-15 15:58:58 +03002323 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002324}
2325
2326static bool ValidateObjectPtrName(Context *context, const void *ptr)
2327{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002328 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002329 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002330 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 return false;
2332 }
2333
Geoff Lange102fee2015-12-10 11:23:30 -05002334 return true;
2335}
2336
2337bool ValidateObjectPtrLabelKHR(Context *context,
2338 const void *ptr,
2339 GLsizei length,
2340 const GLchar *label)
2341{
2342 if (!context->getExtensions().debug)
2343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002345 return false;
2346 }
2347
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 if (!ValidateObjectPtrName(context, ptr))
2349 {
2350 return false;
2351 }
2352
Martin Radev9d901792016-07-15 15:58:58 +03002353 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002354 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002355 return false;
2356 }
2357
Geoff Lange102fee2015-12-10 11:23:30 -05002358 return true;
2359}
2360
2361bool ValidateGetObjectPtrLabelKHR(Context *context,
2362 const void *ptr,
2363 GLsizei bufSize,
2364 GLsizei *length,
2365 GLchar *label)
2366{
2367 if (!context->getExtensions().debug)
2368 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002369 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002370 return false;
2371 }
2372
Geoff Lang70d0f492015-12-10 17:45:46 -05002373 if (bufSize < 0)
2374 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002375 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002376 return false;
2377 }
2378
2379 if (!ValidateObjectPtrName(context, ptr))
2380 {
2381 return false;
2382 }
2383
Martin Radev9d901792016-07-15 15:58:58 +03002384 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002385}
2386
2387bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2388{
2389 if (!context->getExtensions().debug)
2390 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002392 return false;
2393 }
2394
Geoff Lang70d0f492015-12-10 17:45:46 -05002395 // TODO: represent this in Context::getQueryParameterInfo.
2396 switch (pname)
2397 {
2398 case GL_DEBUG_CALLBACK_FUNCTION:
2399 case GL_DEBUG_CALLBACK_USER_PARAM:
2400 break;
2401
2402 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002403 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 return false;
2405 }
2406
Geoff Lange102fee2015-12-10 11:23:30 -05002407 return true;
2408}
Jamie Madillc29968b2016-01-20 11:17:23 -05002409
2410bool ValidateBlitFramebufferANGLE(Context *context,
2411 GLint srcX0,
2412 GLint srcY0,
2413 GLint srcX1,
2414 GLint srcY1,
2415 GLint dstX0,
2416 GLint dstY0,
2417 GLint dstX1,
2418 GLint dstY1,
2419 GLbitfield mask,
2420 GLenum filter)
2421{
2422 if (!context->getExtensions().framebufferBlit)
2423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002424 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002425 return false;
2426 }
2427
2428 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2429 {
2430 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002431 context->handleError(InvalidOperation() << "Scaling and flipping in "
2432 "BlitFramebufferANGLE not supported by this "
2433 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002434 return false;
2435 }
2436
2437 if (filter == GL_LINEAR)
2438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 return false;
2441 }
2442
Jamie Madill51f40ec2016-06-15 14:06:00 -04002443 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2444 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002445
2446 if (mask & GL_COLOR_BUFFER_BIT)
2447 {
2448 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2449 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2450
2451 if (readColorAttachment && drawColorAttachment)
2452 {
2453 if (!(readColorAttachment->type() == GL_TEXTURE &&
2454 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2455 readColorAttachment->type() != GL_RENDERBUFFER &&
2456 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002458 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
Geoff Langa15472a2015-08-11 11:48:03 -04002462 for (size_t drawbufferIdx = 0;
2463 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002464 {
Geoff Langa15472a2015-08-11 11:48:03 -04002465 const FramebufferAttachment *attachment =
2466 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2467 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002468 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002469 if (!(attachment->type() == GL_TEXTURE &&
2470 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2471 attachment->type() != GL_RENDERBUFFER &&
2472 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002474 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002475 return false;
2476 }
2477
2478 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002479 if (!Format::EquivalentForBlit(attachment->getFormat(),
2480 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002482 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485 }
2486 }
2487
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002488 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2490 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2491 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002492 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002493 return false;
2494 }
2495 }
2496 }
2497
2498 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2499 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2500 for (size_t i = 0; i < 2; i++)
2501 {
2502 if (mask & masks[i])
2503 {
2504 const FramebufferAttachment *readBuffer =
2505 readFramebuffer->getAttachment(attachments[i]);
2506 const FramebufferAttachment *drawBuffer =
2507 drawFramebuffer->getAttachment(attachments[i]);
2508
2509 if (readBuffer && drawBuffer)
2510 {
2511 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2512 dstX0, dstY0, dstX1, dstY1))
2513 {
2514 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002515 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2516 "stencil blits are supported by "
2517 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002518 return false;
2519 }
2520
2521 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2522 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002523 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002524 return false;
2525 }
2526 }
2527 }
2528 }
2529
2530 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2531 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002532}
Jamie Madillc29968b2016-01-20 11:17:23 -05002533
2534bool ValidateClear(ValidationContext *context, GLbitfield mask)
2535{
Jamie Madill51f40ec2016-06-15 14:06:00 -04002536 auto fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002537 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002539 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 return false;
2541 }
2542
2543 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2544 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002545 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002546 return false;
2547 }
2548
Geoff Lang76e65652017-03-27 14:58:02 -04002549 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2550 {
2551 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2552 GL_SIGNED_NORMALIZED};
2553
Corentin Wallez59c41592017-07-11 13:19:54 -04002554 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002555 drawBufferIdx++)
2556 {
2557 if (!ValidateWebGLFramebufferAttachmentClearType(
2558 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2559 {
2560 return false;
2561 }
2562 }
2563 }
2564
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 return true;
2566}
2567
2568bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2569{
2570 if (!context->getExtensions().drawBuffers)
2571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002572 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002573 return false;
2574 }
2575
2576 return ValidateDrawBuffersBase(context, n, bufs);
2577}
2578
Jamie Madill73a84962016-02-12 09:27:23 -05002579bool ValidateTexImage2D(Context *context,
2580 GLenum target,
2581 GLint level,
2582 GLint internalformat,
2583 GLsizei width,
2584 GLsizei height,
2585 GLint border,
2586 GLenum format,
2587 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002588 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002589{
Martin Radev1be913c2016-07-11 17:59:16 +03002590 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002591 {
2592 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002593 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002594 }
2595
Martin Radev1be913c2016-07-11 17:59:16 +03002596 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002597 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002598 0, 0, width, height, 1, border, format, type, -1,
2599 pixels);
2600}
2601
2602bool ValidateTexImage2DRobust(Context *context,
2603 GLenum target,
2604 GLint level,
2605 GLint internalformat,
2606 GLsizei width,
2607 GLsizei height,
2608 GLint border,
2609 GLenum format,
2610 GLenum type,
2611 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002612 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002613{
2614 if (!ValidateRobustEntryPoint(context, bufSize))
2615 {
2616 return false;
2617 }
2618
2619 if (context->getClientMajorVersion() < 3)
2620 {
2621 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2622 0, 0, width, height, border, format, type, bufSize,
2623 pixels);
2624 }
2625
2626 ASSERT(context->getClientMajorVersion() >= 3);
2627 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2628 0, 0, width, height, 1, border, format, type, bufSize,
2629 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002630}
2631
2632bool ValidateTexSubImage2D(Context *context,
2633 GLenum target,
2634 GLint level,
2635 GLint xoffset,
2636 GLint yoffset,
2637 GLsizei width,
2638 GLsizei height,
2639 GLenum format,
2640 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002641 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002642{
2643
Martin Radev1be913c2016-07-11 17:59:16 +03002644 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002645 {
2646 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002647 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002648 }
2649
Martin Radev1be913c2016-07-11 17:59:16 +03002650 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002651 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002652 yoffset, 0, width, height, 1, 0, format, type, -1,
2653 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002654}
2655
Geoff Langc52f6f12016-10-14 10:18:00 -04002656bool ValidateTexSubImage2DRobustANGLE(Context *context,
2657 GLenum target,
2658 GLint level,
2659 GLint xoffset,
2660 GLint yoffset,
2661 GLsizei width,
2662 GLsizei height,
2663 GLenum format,
2664 GLenum type,
2665 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002666 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002667{
2668 if (!ValidateRobustEntryPoint(context, bufSize))
2669 {
2670 return false;
2671 }
2672
2673 if (context->getClientMajorVersion() < 3)
2674 {
2675 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2676 yoffset, width, height, 0, format, type, bufSize,
2677 pixels);
2678 }
2679
2680 ASSERT(context->getClientMajorVersion() >= 3);
2681 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2682 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2683 pixels);
2684}
2685
Jamie Madill73a84962016-02-12 09:27:23 -05002686bool ValidateCompressedTexImage2D(Context *context,
2687 GLenum target,
2688 GLint level,
2689 GLenum internalformat,
2690 GLsizei width,
2691 GLsizei height,
2692 GLint border,
2693 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002694 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002695{
Martin Radev1be913c2016-07-11 17:59:16 +03002696 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002697 {
2698 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002699 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002700 {
2701 return false;
2702 }
2703 }
2704 else
2705 {
Martin Radev1be913c2016-07-11 17:59:16 +03002706 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002707 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002708 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002709 data))
2710 {
2711 return false;
2712 }
2713 }
2714
Geoff Langca271392017-04-05 12:30:00 -04002715 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madill513558d2016-06-02 13:04:11 -04002716 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002717 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, 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);
Jamie Madill513558d2016-06-02 13:04:11 -04002810 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002811 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002812 if (blockSizeOrErr.isError())
2813 {
2814 context->handleError(blockSizeOrErr.getError());
2815 return false;
2816 }
2817
2818 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002820 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002821 return false;
2822 }
2823
2824 return true;
2825}
2826
Olli Etuaho4f667482016-03-30 15:56:35 +03002827bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
2828{
Geoff Lang496c02d2016-10-20 11:38:11 -07002829 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002830}
2831
2832bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
2833{
2834 if (!context->getExtensions().mapBuffer)
2835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002836 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002837 return false;
2838 }
2839
2840 if (!ValidBufferTarget(context, target))
2841 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002843 return false;
2844 }
2845
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002846 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002847
2848 if (buffer == nullptr)
2849 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002850 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002851 return false;
2852 }
2853
2854 if (access != GL_WRITE_ONLY_OES)
2855 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002856 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002857 return false;
2858 }
2859
2860 if (buffer->isMapped())
2861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002862 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002863 return false;
2864 }
2865
Geoff Lang79f71042017-08-14 16:43:43 -04002866 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002867}
2868
2869bool ValidateUnmapBufferOES(Context *context, GLenum target)
2870{
2871 if (!context->getExtensions().mapBuffer)
2872 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002873 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002874 return false;
2875 }
2876
2877 return ValidateUnmapBufferBase(context, target);
2878}
2879
2880bool ValidateMapBufferRangeEXT(Context *context,
2881 GLenum target,
2882 GLintptr offset,
2883 GLsizeiptr length,
2884 GLbitfield access)
2885{
2886 if (!context->getExtensions().mapBufferRange)
2887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002888 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002889 return false;
2890 }
2891
2892 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2893}
2894
Geoff Lang79f71042017-08-14 16:43:43 -04002895bool ValidateMapBufferBase(Context *context, GLenum target)
2896{
2897 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2898 ASSERT(buffer != nullptr);
2899
2900 // Check if this buffer is currently being used as a transform feedback output buffer
2901 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2902 if (transformFeedback != nullptr && transformFeedback->isActive())
2903 {
2904 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2905 {
2906 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2907 if (transformFeedbackBuffer.get() == buffer)
2908 {
2909 context->handleError(InvalidOperation()
2910 << "Buffer is currently bound for transform feedback.");
2911 return false;
2912 }
2913 }
2914 }
2915
2916 return true;
2917}
2918
Olli Etuaho4f667482016-03-30 15:56:35 +03002919bool ValidateFlushMappedBufferRangeEXT(Context *context,
2920 GLenum target,
2921 GLintptr offset,
2922 GLsizeiptr length)
2923{
2924 if (!context->getExtensions().mapBufferRange)
2925 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002926 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002927 return false;
2928 }
2929
2930 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2931}
2932
Ian Ewell54f87462016-03-10 13:47:21 -05002933bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
2934{
2935 Texture *textureObject = context->getTexture(texture);
2936 if (textureObject && textureObject->getTarget() != target && texture != 0)
2937 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002938 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002939 return false;
2940 }
2941
Geoff Langf41a7152016-09-19 15:11:17 -04002942 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2943 !context->isTextureGenerated(texture))
2944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002945 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002946 return false;
2947 }
2948
Ian Ewell54f87462016-03-10 13:47:21 -05002949 switch (target)
2950 {
2951 case GL_TEXTURE_2D:
2952 case GL_TEXTURE_CUBE_MAP:
2953 break;
2954
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002955 case GL_TEXTURE_RECTANGLE_ANGLE:
2956 if (!context->getExtensions().textureRectangle)
2957 {
2958 context->handleError(InvalidEnum()
2959 << "Context does not support GL_ANGLE_texture_rectangle");
2960 return false;
2961 }
2962 break;
2963
Ian Ewell54f87462016-03-10 13:47:21 -05002964 case GL_TEXTURE_3D:
2965 case GL_TEXTURE_2D_ARRAY:
Martin Radev1be913c2016-07-11 17:59:16 +03002966 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002967 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002968 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002969 return false;
2970 }
2971 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002972
2973 case GL_TEXTURE_2D_MULTISAMPLE:
2974 if (context->getClientVersion() < Version(3, 1))
2975 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002976 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002977 return false;
2978 }
Geoff Lang3b573612016-10-31 14:08:10 -04002979 break;
2980
Ian Ewell54f87462016-03-10 13:47:21 -05002981 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002982 if (!context->getExtensions().eglImageExternal &&
2983 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002985 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002986 return false;
2987 }
2988 break;
2989 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002990 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002991 return false;
2992 }
2993
2994 return true;
2995}
2996
Geoff Langd8605522016-04-13 10:19:12 -04002997bool ValidateBindUniformLocationCHROMIUM(Context *context,
2998 GLuint program,
2999 GLint location,
3000 const GLchar *name)
3001{
3002 if (!context->getExtensions().bindUniformLocation)
3003 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003004 context->handleError(InvalidOperation()
3005 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003006 return false;
3007 }
3008
3009 Program *programObject = GetValidProgram(context, program);
3010 if (!programObject)
3011 {
3012 return false;
3013 }
3014
3015 if (location < 0)
3016 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003017 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003018 return false;
3019 }
3020
3021 const Caps &caps = context->getCaps();
3022 if (static_cast<size_t>(location) >=
3023 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003025 context->handleError(InvalidValue() << "Location must be less than "
3026 "(MAX_VERTEX_UNIFORM_VECTORS + "
3027 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003028 return false;
3029 }
3030
Geoff Langfc32e8b2017-05-31 14:16:59 -04003031 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3032 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003033 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003034 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003035 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003036 return false;
3037 }
3038
Geoff Langd8605522016-04-13 10:19:12 -04003039 if (strncmp(name, "gl_", 3) == 0)
3040 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003041 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003042 return false;
3043 }
3044
3045 return true;
3046}
3047
Jamie Madille2e406c2016-06-02 13:04:10 -04003048bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003049{
3050 if (!context->getExtensions().framebufferMixedSamples)
3051 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003052 context->handleError(InvalidOperation()
3053 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003054 return false;
3055 }
3056 switch (components)
3057 {
3058 case GL_RGB:
3059 case GL_RGBA:
3060 case GL_ALPHA:
3061 case GL_NONE:
3062 break;
3063 default:
3064 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003065 InvalidEnum()
3066 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003067 return false;
3068 }
3069
3070 return true;
3071}
3072
Sami Väisänene45e53b2016-05-25 10:36:04 +03003073// CHROMIUM_path_rendering
3074
3075bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
3076{
3077 if (!context->getExtensions().pathRendering)
3078 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003079 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003080 return false;
3081 }
3082 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3083 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003084 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003085 return false;
3086 }
3087 if (matrix == nullptr)
3088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003089 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003090 return false;
3091 }
3092 return true;
3093}
3094
3095bool ValidateMatrixMode(Context *context, GLenum matrixMode)
3096{
3097 if (!context->getExtensions().pathRendering)
3098 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003099 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003100 return false;
3101 }
3102 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3103 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003104 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 return false;
3106 }
3107 return true;
3108}
3109
3110bool ValidateGenPaths(Context *context, GLsizei range)
3111{
3112 if (!context->getExtensions().pathRendering)
3113 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003114 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003115 return false;
3116 }
3117
3118 // range = 0 is undefined in NV_path_rendering.
3119 // we add stricter semantic check here and require a non zero positive range.
3120 if (range <= 0)
3121 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003122 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003123 return false;
3124 }
3125
3126 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3127 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003128 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003129 return false;
3130 }
3131
3132 return true;
3133}
3134
3135bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
3136{
3137 if (!context->getExtensions().pathRendering)
3138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003139 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003140 return false;
3141 }
3142
3143 // range = 0 is undefined in NV_path_rendering.
3144 // we add stricter semantic check here and require a non zero positive range.
3145 if (range <= 0)
3146 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003147 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003148 return false;
3149 }
3150
3151 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3152 checkedRange += range;
3153
3154 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003156 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003157 return false;
3158 }
3159 return true;
3160}
3161
3162bool ValidatePathCommands(Context *context,
3163 GLuint path,
3164 GLsizei numCommands,
3165 const GLubyte *commands,
3166 GLsizei numCoords,
3167 GLenum coordType,
3168 const void *coords)
3169{
3170 if (!context->getExtensions().pathRendering)
3171 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003172 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003173 return false;
3174 }
3175 if (!context->hasPath(path))
3176 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003177 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003178 return false;
3179 }
3180
3181 if (numCommands < 0)
3182 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003183 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003184 return false;
3185 }
3186 else if (numCommands > 0)
3187 {
3188 if (!commands)
3189 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003190 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003191 return false;
3192 }
3193 }
3194
3195 if (numCoords < 0)
3196 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003197 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 return false;
3199 }
3200 else if (numCoords > 0)
3201 {
3202 if (!coords)
3203 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003204 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003205 return false;
3206 }
3207 }
3208
3209 std::uint32_t coordTypeSize = 0;
3210 switch (coordType)
3211 {
3212 case GL_BYTE:
3213 coordTypeSize = sizeof(GLbyte);
3214 break;
3215
3216 case GL_UNSIGNED_BYTE:
3217 coordTypeSize = sizeof(GLubyte);
3218 break;
3219
3220 case GL_SHORT:
3221 coordTypeSize = sizeof(GLshort);
3222 break;
3223
3224 case GL_UNSIGNED_SHORT:
3225 coordTypeSize = sizeof(GLushort);
3226 break;
3227
3228 case GL_FLOAT:
3229 coordTypeSize = sizeof(GLfloat);
3230 break;
3231
3232 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003233 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003234 return false;
3235 }
3236
3237 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3238 checkedSize += (coordTypeSize * numCoords);
3239 if (!checkedSize.IsValid())
3240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003242 return false;
3243 }
3244
3245 // early return skips command data validation when it doesn't exist.
3246 if (!commands)
3247 return true;
3248
3249 GLsizei expectedNumCoords = 0;
3250 for (GLsizei i = 0; i < numCommands; ++i)
3251 {
3252 switch (commands[i])
3253 {
3254 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3255 break;
3256 case GL_MOVE_TO_CHROMIUM:
3257 case GL_LINE_TO_CHROMIUM:
3258 expectedNumCoords += 2;
3259 break;
3260 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3261 expectedNumCoords += 4;
3262 break;
3263 case GL_CUBIC_CURVE_TO_CHROMIUM:
3264 expectedNumCoords += 6;
3265 break;
3266 case GL_CONIC_CURVE_TO_CHROMIUM:
3267 expectedNumCoords += 5;
3268 break;
3269 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003270 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003271 return false;
3272 }
3273 }
3274 if (expectedNumCoords != numCoords)
3275 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003276 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277 return false;
3278 }
3279
3280 return true;
3281}
3282
3283bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
3284{
3285 if (!context->getExtensions().pathRendering)
3286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003287 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003288 return false;
3289 }
3290 if (!context->hasPath(path))
3291 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003292 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293 return false;
3294 }
3295
3296 switch (pname)
3297 {
3298 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3299 if (value < 0.0f)
3300 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003301 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 return false;
3303 }
3304 break;
3305 case GL_PATH_END_CAPS_CHROMIUM:
3306 switch (static_cast<GLenum>(value))
3307 {
3308 case GL_FLAT_CHROMIUM:
3309 case GL_SQUARE_CHROMIUM:
3310 case GL_ROUND_CHROMIUM:
3311 break;
3312 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003313 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003314 return false;
3315 }
3316 break;
3317 case GL_PATH_JOIN_STYLE_CHROMIUM:
3318 switch (static_cast<GLenum>(value))
3319 {
3320 case GL_MITER_REVERT_CHROMIUM:
3321 case GL_BEVEL_CHROMIUM:
3322 case GL_ROUND_CHROMIUM:
3323 break;
3324 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003325 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003326 return false;
3327 }
3328 case GL_PATH_MITER_LIMIT_CHROMIUM:
3329 if (value < 0.0f)
3330 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003331 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003332 return false;
3333 }
3334 break;
3335
3336 case GL_PATH_STROKE_BOUND_CHROMIUM:
3337 // no errors, only clamping.
3338 break;
3339
3340 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
3344 return true;
3345}
3346
3347bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
3348{
3349 if (!context->getExtensions().pathRendering)
3350 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003351 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003352 return false;
3353 }
3354
3355 if (!context->hasPath(path))
3356 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003358 return false;
3359 }
3360 if (!value)
3361 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003362 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003363 return false;
3364 }
3365
3366 switch (pname)
3367 {
3368 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3369 case GL_PATH_END_CAPS_CHROMIUM:
3370 case GL_PATH_JOIN_STYLE_CHROMIUM:
3371 case GL_PATH_MITER_LIMIT_CHROMIUM:
3372 case GL_PATH_STROKE_BOUND_CHROMIUM:
3373 break;
3374
3375 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003376 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003377 return false;
3378 }
3379
3380 return true;
3381}
3382
3383bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
3384{
3385 if (!context->getExtensions().pathRendering)
3386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003387 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003388 return false;
3389 }
3390
3391 switch (func)
3392 {
3393 case GL_NEVER:
3394 case GL_ALWAYS:
3395 case GL_LESS:
3396 case GL_LEQUAL:
3397 case GL_EQUAL:
3398 case GL_GEQUAL:
3399 case GL_GREATER:
3400 case GL_NOTEQUAL:
3401 break;
3402 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003403 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 return false;
3405 }
3406
3407 return true;
3408}
3409
3410// Note that the spec specifies that for the path drawing commands
3411// if the path object is not an existing path object the command
3412// does nothing and no error is generated.
3413// However if the path object exists but has not been specified any
3414// commands then an error is generated.
3415
3416bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
3417{
3418 if (!context->getExtensions().pathRendering)
3419 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003420 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003421 return false;
3422 }
3423 if (context->hasPath(path) && !context->hasPathData(path))
3424 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003426 return false;
3427 }
3428
3429 switch (fillMode)
3430 {
3431 case GL_COUNT_UP_CHROMIUM:
3432 case GL_COUNT_DOWN_CHROMIUM:
3433 break;
3434 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003435 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003436 return false;
3437 }
3438
3439 if (!isPow2(mask + 1))
3440 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003441 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003442 return false;
3443 }
3444
3445 return true;
3446}
3447
3448bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
3449{
3450 if (!context->getExtensions().pathRendering)
3451 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003452 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003453 return false;
3454 }
3455 if (context->hasPath(path) && !context->hasPathData(path))
3456 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003457 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003458 return false;
3459 }
3460
3461 return true;
3462}
3463
3464bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode)
3465{
3466 if (!context->getExtensions().pathRendering)
3467 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003468 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003469 return false;
3470 }
3471 if (context->hasPath(path) && !context->hasPathData(path))
3472 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003473 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003474 return false;
3475 }
3476
3477 switch (coverMode)
3478 {
3479 case GL_CONVEX_HULL_CHROMIUM:
3480 case GL_BOUNDING_BOX_CHROMIUM:
3481 break;
3482 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003483 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003484 return false;
3485 }
3486 return true;
3487}
3488
3489bool ValidateStencilThenCoverFillPath(Context *context,
3490 GLuint path,
3491 GLenum fillMode,
3492 GLuint mask,
3493 GLenum coverMode)
3494{
3495 return ValidateStencilFillPath(context, path, fillMode, mask) &&
3496 ValidateCoverPath(context, path, coverMode);
3497}
3498
3499bool ValidateStencilThenCoverStrokePath(Context *context,
3500 GLuint path,
3501 GLint reference,
3502 GLuint mask,
3503 GLenum coverMode)
3504{
3505 return ValidateStencilStrokePath(context, path, reference, mask) &&
3506 ValidateCoverPath(context, path, coverMode);
3507}
3508
3509bool ValidateIsPath(Context *context)
3510{
3511 if (!context->getExtensions().pathRendering)
3512 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003513 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003514 return false;
3515 }
3516 return true;
3517}
3518
Sami Väisänend59ca052016-06-21 16:10:00 +03003519bool ValidateCoverFillPathInstanced(Context *context,
3520 GLsizei numPaths,
3521 GLenum pathNameType,
3522 const void *paths,
3523 GLuint pathBase,
3524 GLenum coverMode,
3525 GLenum transformType,
3526 const GLfloat *transformValues)
3527{
3528 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3529 transformType, transformValues))
3530 return false;
3531
3532 switch (coverMode)
3533 {
3534 case GL_CONVEX_HULL_CHROMIUM:
3535 case GL_BOUNDING_BOX_CHROMIUM:
3536 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3537 break;
3538 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003539 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003540 return false;
3541 }
3542
3543 return true;
3544}
3545
3546bool ValidateCoverStrokePathInstanced(Context *context,
3547 GLsizei numPaths,
3548 GLenum pathNameType,
3549 const void *paths,
3550 GLuint pathBase,
3551 GLenum coverMode,
3552 GLenum transformType,
3553 const GLfloat *transformValues)
3554{
3555 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3556 transformType, transformValues))
3557 return false;
3558
3559 switch (coverMode)
3560 {
3561 case GL_CONVEX_HULL_CHROMIUM:
3562 case GL_BOUNDING_BOX_CHROMIUM:
3563 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3564 break;
3565 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003566 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003567 return false;
3568 }
3569
3570 return true;
3571}
3572
3573bool ValidateStencilFillPathInstanced(Context *context,
3574 GLsizei numPaths,
3575 GLenum pathNameType,
3576 const void *paths,
3577 GLuint pathBase,
3578 GLenum fillMode,
3579 GLuint mask,
3580 GLenum transformType,
3581 const GLfloat *transformValues)
3582{
3583
3584 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3585 transformType, transformValues))
3586 return false;
3587
3588 switch (fillMode)
3589 {
3590 case GL_COUNT_UP_CHROMIUM:
3591 case GL_COUNT_DOWN_CHROMIUM:
3592 break;
3593 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003595 return false;
3596 }
3597 if (!isPow2(mask + 1))
3598 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003599 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003600 return false;
3601 }
3602 return true;
3603}
3604
3605bool ValidateStencilStrokePathInstanced(Context *context,
3606 GLsizei numPaths,
3607 GLenum pathNameType,
3608 const void *paths,
3609 GLuint pathBase,
3610 GLint reference,
3611 GLuint mask,
3612 GLenum transformType,
3613 const GLfloat *transformValues)
3614{
3615 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3616 transformType, transformValues))
3617 return false;
3618
3619 // no more validation here.
3620
3621 return true;
3622}
3623
3624bool ValidateStencilThenCoverFillPathInstanced(Context *context,
3625 GLsizei numPaths,
3626 GLenum pathNameType,
3627 const void *paths,
3628 GLuint pathBase,
3629 GLenum fillMode,
3630 GLuint mask,
3631 GLenum coverMode,
3632 GLenum transformType,
3633 const GLfloat *transformValues)
3634{
3635 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3636 transformType, transformValues))
3637 return false;
3638
3639 switch (coverMode)
3640 {
3641 case GL_CONVEX_HULL_CHROMIUM:
3642 case GL_BOUNDING_BOX_CHROMIUM:
3643 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3644 break;
3645 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003646 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003647 return false;
3648 }
3649
3650 switch (fillMode)
3651 {
3652 case GL_COUNT_UP_CHROMIUM:
3653 case GL_COUNT_DOWN_CHROMIUM:
3654 break;
3655 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003656 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003657 return false;
3658 }
3659 if (!isPow2(mask + 1))
3660 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003661 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003662 return false;
3663 }
3664
3665 return true;
3666}
3667
3668bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
3669 GLsizei numPaths,
3670 GLenum pathNameType,
3671 const void *paths,
3672 GLuint pathBase,
3673 GLint reference,
3674 GLuint mask,
3675 GLenum coverMode,
3676 GLenum transformType,
3677 const GLfloat *transformValues)
3678{
3679 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3680 transformType, transformValues))
3681 return false;
3682
3683 switch (coverMode)
3684 {
3685 case GL_CONVEX_HULL_CHROMIUM:
3686 case GL_BOUNDING_BOX_CHROMIUM:
3687 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3688 break;
3689 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003690 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003691 return false;
3692 }
3693
3694 return true;
3695}
3696
Sami Väisänen46eaa942016-06-29 10:26:37 +03003697bool ValidateBindFragmentInputLocation(Context *context,
3698 GLuint program,
3699 GLint location,
3700 const GLchar *name)
3701{
3702 if (!context->getExtensions().pathRendering)
3703 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003704 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003705 return false;
3706 }
3707
3708 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3709 if (location >= MaxLocation)
3710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003711 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003712 return false;
3713 }
3714
3715 const auto *programObject = context->getProgram(program);
3716 if (!programObject)
3717 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003718 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003719 return false;
3720 }
3721
3722 if (!name)
3723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003724 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003725 return false;
3726 }
3727
3728 if (angle::BeginsWith(name, "gl_"))
3729 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003730 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003731 return false;
3732 }
3733
3734 return true;
3735}
3736
3737bool ValidateProgramPathFragmentInputGen(Context *context,
3738 GLuint program,
3739 GLint location,
3740 GLenum genMode,
3741 GLint components,
3742 const GLfloat *coeffs)
3743{
3744 if (!context->getExtensions().pathRendering)
3745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003746 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003747 return false;
3748 }
3749
3750 const auto *programObject = context->getProgram(program);
3751 if (!programObject || programObject->isFlaggedForDeletion())
3752 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003753 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003754 return false;
3755 }
3756
3757 if (!programObject->isLinked())
3758 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003759 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003760 return false;
3761 }
3762
3763 switch (genMode)
3764 {
3765 case GL_NONE:
3766 if (components != 0)
3767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003768 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003769 return false;
3770 }
3771 break;
3772
3773 case GL_OBJECT_LINEAR_CHROMIUM:
3774 case GL_EYE_LINEAR_CHROMIUM:
3775 case GL_CONSTANT_CHROMIUM:
3776 if (components < 1 || components > 4)
3777 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003778 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003779 return false;
3780 }
3781 if (!coeffs)
3782 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003783 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003784 return false;
3785 }
3786 break;
3787
3788 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003789 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003790 return false;
3791 }
3792
3793 // If the location is -1 then the command is silently ignored
3794 // and no further validation is needed.
3795 if (location == -1)
3796 return true;
3797
Jamie Madillbd044ed2017-06-05 12:59:21 -04003798 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003799
3800 if (!binding.valid)
3801 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003802 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003803 return false;
3804 }
3805
3806 if (binding.type != GL_NONE)
3807 {
3808 GLint expectedComponents = 0;
3809 switch (binding.type)
3810 {
3811 case GL_FLOAT:
3812 expectedComponents = 1;
3813 break;
3814 case GL_FLOAT_VEC2:
3815 expectedComponents = 2;
3816 break;
3817 case GL_FLOAT_VEC3:
3818 expectedComponents = 3;
3819 break;
3820 case GL_FLOAT_VEC4:
3821 expectedComponents = 4;
3822 break;
3823 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003824 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003825 InvalidOperation()
3826 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003827 return false;
3828 }
3829 if (expectedComponents != components && genMode != GL_NONE)
3830 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003831 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003832 return false;
3833 }
3834 }
3835 return true;
3836}
3837
Geoff Lang97073d12016-04-20 10:42:34 -07003838bool ValidateCopyTextureCHROMIUM(Context *context,
3839 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003840 GLint sourceLevel,
3841 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003842 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003843 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003844 GLint internalFormat,
3845 GLenum destType,
3846 GLboolean unpackFlipY,
3847 GLboolean unpackPremultiplyAlpha,
3848 GLboolean unpackUnmultiplyAlpha)
3849{
3850 if (!context->getExtensions().copyTexture)
3851 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003852 context->handleError(InvalidOperation()
3853 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003854 return false;
3855 }
3856
Geoff Lang4f0e0032017-05-01 16:04:35 -04003857 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003858 if (source == nullptr)
3859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003860 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003861 return false;
3862 }
3863
3864 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003866 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003867 return false;
3868 }
3869
3870 GLenum sourceTarget = source->getTarget();
3871 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003872
3873 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003874 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003875 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003876 return false;
3877 }
3878
Geoff Lang4f0e0032017-05-01 16:04:35 -04003879 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3880 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3881 if (sourceWidth == 0 || sourceHeight == 0)
3882 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003883 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003884 return false;
3885 }
3886
3887 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3888 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003889 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003890 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003891 return false;
3892 }
3893
Geoff Lang63458a32017-10-30 15:16:53 -04003894 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3895 {
3896 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3897 return false;
3898 }
3899
Geoff Lang4f0e0032017-05-01 16:04:35 -04003900 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003901 if (dest == nullptr)
3902 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003903 context->handleError(InvalidValue()
3904 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003905 return false;
3906 }
3907
Geoff Lang4f0e0032017-05-01 16:04:35 -04003908 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003909 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003910 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003911 return false;
3912 }
3913
Geoff Lang4f0e0032017-05-01 16:04:35 -04003914 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3915 sourceHeight))
3916 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003917 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003918 return false;
3919 }
3920
Geoff Lang97073d12016-04-20 10:42:34 -07003921 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3922 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003923 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003924 return false;
3925 }
3926
Geoff Lang4f0e0032017-05-01 16:04:35 -04003927 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3928 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003929 context->handleError(
3930 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003931 return false;
3932 }
3933
Geoff Lang97073d12016-04-20 10:42:34 -07003934 if (dest->getImmutableFormat())
3935 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003936 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003937 return false;
3938 }
3939
3940 return true;
3941}
3942
3943bool ValidateCopySubTextureCHROMIUM(Context *context,
3944 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003945 GLint sourceLevel,
3946 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003947 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003948 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003949 GLint xoffset,
3950 GLint yoffset,
3951 GLint x,
3952 GLint y,
3953 GLsizei width,
3954 GLsizei height,
3955 GLboolean unpackFlipY,
3956 GLboolean unpackPremultiplyAlpha,
3957 GLboolean unpackUnmultiplyAlpha)
3958{
3959 if (!context->getExtensions().copyTexture)
3960 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003961 context->handleError(InvalidOperation()
3962 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003963 return false;
3964 }
3965
Geoff Lang4f0e0032017-05-01 16:04:35 -04003966 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003967 if (source == nullptr)
3968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003969 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003970 return false;
3971 }
3972
3973 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3974 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003975 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003976 return false;
3977 }
3978
3979 GLenum sourceTarget = source->getTarget();
3980 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003981
3982 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3983 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003984 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003985 return false;
3986 }
3987
3988 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3989 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07003990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidValue()
3992 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07003993 return false;
3994 }
3995
3996 if (x < 0 || y < 0)
3997 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003998 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07003999 return false;
4000 }
4001
4002 if (width < 0 || height < 0)
4003 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004004 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004005 return false;
4006 }
4007
Geoff Lang4f0e0032017-05-01 16:04:35 -04004008 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4009 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004010 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004011 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004012 return false;
4013 }
4014
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4016 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004017 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004018 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004019 return false;
4020 }
4021
Geoff Lang63458a32017-10-30 15:16:53 -04004022 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4023 {
4024 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4025 return false;
4026 }
4027
Geoff Lang4f0e0032017-05-01 16:04:35 -04004028 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004029 if (dest == nullptr)
4030 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004031 context->handleError(InvalidValue()
4032 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004033 return false;
4034 }
4035
Geoff Lang4f0e0032017-05-01 16:04:35 -04004036 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004038 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004039 return false;
4040 }
4041
Geoff Lang4f0e0032017-05-01 16:04:35 -04004042 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07004043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004044 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004045 return false;
4046 }
4047
Geoff Lang4f0e0032017-05-01 16:04:35 -04004048 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4049 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004050 context
4051 ->handleError(InvalidOperation()
4052 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004053 return false;
4054 }
4055
4056 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4057 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004059 context->handleError(InvalidOperation()
4060 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004061 return false;
4062 }
4063
4064 if (xoffset < 0 || yoffset < 0)
4065 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004066 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004067 return false;
4068 }
4069
Geoff Lang4f0e0032017-05-01 16:04:35 -04004070 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4071 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004072 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004073 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004074 return false;
4075 }
4076
4077 return true;
4078}
4079
Geoff Lang47110bf2016-04-20 11:13:22 -07004080bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4081{
4082 if (!context->getExtensions().copyCompressedTexture)
4083 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004084 context->handleError(InvalidOperation()
4085 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004086 return false;
4087 }
4088
4089 const gl::Texture *source = context->getTexture(sourceId);
4090 if (source == nullptr)
4091 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004092 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004093 return false;
4094 }
4095
4096 if (source->getTarget() != GL_TEXTURE_2D)
4097 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004098 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004099 return false;
4100 }
4101
4102 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004105 return false;
4106 }
4107
4108 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4109 if (!sourceFormat.info->compressed)
4110 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004111 context->handleError(InvalidOperation()
4112 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004113 return false;
4114 }
4115
4116 const gl::Texture *dest = context->getTexture(destId);
4117 if (dest == nullptr)
4118 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004119 context->handleError(InvalidValue()
4120 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004121 return false;
4122 }
4123
4124 if (dest->getTarget() != GL_TEXTURE_2D)
4125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004126 context->handleError(InvalidValue()
4127 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004128 return false;
4129 }
4130
4131 if (dest->getImmutableFormat())
4132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004133 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 return false;
4135 }
4136
4137 return true;
4138}
4139
Martin Radev4c4c8e72016-08-04 12:25:34 +03004140bool ValidateCreateShader(Context *context, GLenum type)
4141{
4142 switch (type)
4143 {
4144 case GL_VERTEX_SHADER:
4145 case GL_FRAGMENT_SHADER:
4146 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004147
Martin Radev4c4c8e72016-08-04 12:25:34 +03004148 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004149 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004150 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004151 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004152 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004153 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004154 break;
4155
Martin Radev4c4c8e72016-08-04 12:25:34 +03004156 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004157 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004158 return false;
4159 }
Jamie Madill29639852016-09-02 15:00:09 -04004160
4161 return true;
4162}
4163
4164bool ValidateBufferData(ValidationContext *context,
4165 GLenum target,
4166 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004167 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004168 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004169{
4170 if (size < 0)
4171 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004172 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004173 return false;
4174 }
4175
4176 switch (usage)
4177 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004178 case BufferUsage::StreamDraw:
4179 case BufferUsage::StaticDraw:
4180 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004181 break;
4182
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004183 case BufferUsage::StreamRead:
4184 case BufferUsage::StaticRead:
4185 case BufferUsage::DynamicRead:
4186 case BufferUsage::StreamCopy:
4187 case BufferUsage::StaticCopy:
4188 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004189 if (context->getClientMajorVersion() < 3)
4190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004191 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004192 return false;
4193 }
4194 break;
4195
4196 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004197 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004198 return false;
4199 }
4200
4201 if (!ValidBufferTarget(context, target))
4202 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004204 return false;
4205 }
4206
4207 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4208
4209 if (!buffer)
4210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004211 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004212 return false;
4213 }
4214
4215 return true;
4216}
4217
4218bool ValidateBufferSubData(ValidationContext *context,
4219 GLenum target,
4220 GLintptr offset,
4221 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004222 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004223{
Brandon Jones6cad5662017-06-14 13:25:13 -07004224 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004225 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004226 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4227 return false;
4228 }
4229
4230 if (offset < 0)
4231 {
4232 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004233 return false;
4234 }
4235
4236 if (!ValidBufferTarget(context, target))
4237 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004238 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004239 return false;
4240 }
4241
4242 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4243
4244 if (!buffer)
4245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004247 return false;
4248 }
4249
4250 if (buffer->isMapped())
4251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004252 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004253 return false;
4254 }
4255
4256 // Check for possible overflow of size + offset
4257 angle::CheckedNumeric<size_t> checkedSize(size);
4258 checkedSize += offset;
4259 if (!checkedSize.IsValid())
4260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004261 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004262 return false;
4263 }
4264
4265 if (size + offset > buffer->getSize())
4266 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004267 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004268 return false;
4269 }
4270
Martin Radev4c4c8e72016-08-04 12:25:34 +03004271 return true;
4272}
4273
Geoff Lang111a99e2017-10-17 10:58:41 -04004274bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004275{
Geoff Langc339c4e2016-11-29 10:37:36 -05004276 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004278 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004279 return false;
4280 }
4281
Geoff Lang111a99e2017-10-17 10:58:41 -04004282 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004283 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004284 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004285 return false;
4286 }
4287
4288 return true;
4289}
4290
Jamie Madillef300b12016-10-07 15:12:09 -04004291bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4292{
4293 if (texture < GL_TEXTURE0 ||
4294 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004296 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004297 return false;
4298 }
4299
4300 return true;
4301}
4302
4303bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4304{
4305 Program *programObject = GetValidProgram(context, program);
4306 if (!programObject)
4307 {
4308 return false;
4309 }
4310
4311 Shader *shaderObject = GetValidShader(context, shader);
4312 if (!shaderObject)
4313 {
4314 return false;
4315 }
4316
4317 switch (shaderObject->getType())
4318 {
4319 case GL_VERTEX_SHADER:
4320 {
4321 if (programObject->getAttachedVertexShader())
4322 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004323 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004324 return false;
4325 }
4326 break;
4327 }
4328 case GL_FRAGMENT_SHADER:
4329 {
4330 if (programObject->getAttachedFragmentShader())
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_COMPUTE_SHADER:
4338 {
4339 if (programObject->getAttachedComputeShader())
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 default:
4347 UNREACHABLE();
4348 break;
4349 }
4350
4351 return true;
4352}
4353
Jamie Madill01a80ee2016-11-07 12:06:18 -05004354bool ValidateBindAttribLocation(ValidationContext *context,
4355 GLuint program,
4356 GLuint index,
4357 const GLchar *name)
4358{
4359 if (index >= MAX_VERTEX_ATTRIBS)
4360 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004361 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004362 return false;
4363 }
4364
4365 if (strncmp(name, "gl_", 3) == 0)
4366 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004368 return false;
4369 }
4370
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004371 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004372 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004373 const size_t length = strlen(name);
4374
4375 if (!IsValidESSLString(name, length))
4376 {
4377 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4378 // for shader-related entry points
4379 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4380 return false;
4381 }
4382
4383 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4384 {
4385 return false;
4386 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004387 }
4388
Jamie Madill01a80ee2016-11-07 12:06:18 -05004389 return GetValidProgram(context, program) != nullptr;
4390}
4391
4392bool ValidateBindBuffer(ValidationContext *context, GLenum target, GLuint buffer)
4393{
4394 if (!ValidBufferTarget(context, target))
4395 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004396 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004397 return false;
4398 }
4399
4400 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4401 !context->isBufferGenerated(buffer))
4402 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004403 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004404 return false;
4405 }
4406
4407 return true;
4408}
4409
4410bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4411{
4412 if (!ValidFramebufferTarget(target))
4413 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004414 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415 return false;
4416 }
4417
4418 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4419 !context->isFramebufferGenerated(framebuffer))
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 ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4429{
4430 if (target != GL_RENDERBUFFER)
4431 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004432 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004433 return false;
4434 }
4435
4436 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4437 !context->isRenderbufferGenerated(renderbuffer))
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
Geoff Lang50cac572017-09-26 17:37:43 -04004446static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004447{
4448 switch (mode)
4449 {
4450 case GL_FUNC_ADD:
4451 case GL_FUNC_SUBTRACT:
4452 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004453 return true;
4454
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004455 case GL_MIN:
4456 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004457 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004458
4459 default:
4460 return false;
4461 }
4462}
4463
Jamie Madillc1d770e2017-04-13 17:31:24 -04004464bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004465 GLfloat red,
4466 GLfloat green,
4467 GLfloat blue,
4468 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004469{
4470 return true;
4471}
4472
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004473bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4474{
Geoff Lang50cac572017-09-26 17:37:43 -04004475 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004476 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004478 return false;
4479 }
4480
4481 return true;
4482}
4483
4484bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4485{
Geoff Lang50cac572017-09-26 17:37:43 -04004486 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004487 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004488 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004489 return false;
4490 }
4491
Geoff Lang50cac572017-09-26 17:37:43 -04004492 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004493 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004494 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004495 return false;
4496 }
4497
4498 return true;
4499}
4500
4501bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4502{
4503 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4504}
4505
4506static bool ValidSrcBlendFunc(GLenum srcBlend)
4507{
4508 switch (srcBlend)
4509 {
4510 case GL_ZERO:
4511 case GL_ONE:
4512 case GL_SRC_COLOR:
4513 case GL_ONE_MINUS_SRC_COLOR:
4514 case GL_DST_COLOR:
4515 case GL_ONE_MINUS_DST_COLOR:
4516 case GL_SRC_ALPHA:
4517 case GL_ONE_MINUS_SRC_ALPHA:
4518 case GL_DST_ALPHA:
4519 case GL_ONE_MINUS_DST_ALPHA:
4520 case GL_CONSTANT_COLOR:
4521 case GL_ONE_MINUS_CONSTANT_COLOR:
4522 case GL_CONSTANT_ALPHA:
4523 case GL_ONE_MINUS_CONSTANT_ALPHA:
4524 case GL_SRC_ALPHA_SATURATE:
4525 return true;
4526
4527 default:
4528 return false;
4529 }
4530}
4531
4532static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4533{
4534 switch (dstBlend)
4535 {
4536 case GL_ZERO:
4537 case GL_ONE:
4538 case GL_SRC_COLOR:
4539 case GL_ONE_MINUS_SRC_COLOR:
4540 case GL_DST_COLOR:
4541 case GL_ONE_MINUS_DST_COLOR:
4542 case GL_SRC_ALPHA:
4543 case GL_ONE_MINUS_SRC_ALPHA:
4544 case GL_DST_ALPHA:
4545 case GL_ONE_MINUS_DST_ALPHA:
4546 case GL_CONSTANT_COLOR:
4547 case GL_ONE_MINUS_CONSTANT_COLOR:
4548 case GL_CONSTANT_ALPHA:
4549 case GL_ONE_MINUS_CONSTANT_ALPHA:
4550 return true;
4551
4552 case GL_SRC_ALPHA_SATURATE:
4553 return (contextMajorVersion >= 3);
4554
4555 default:
4556 return false;
4557 }
4558}
4559
4560bool ValidateBlendFuncSeparate(ValidationContext *context,
4561 GLenum srcRGB,
4562 GLenum dstRGB,
4563 GLenum srcAlpha,
4564 GLenum dstAlpha)
4565{
4566 if (!ValidSrcBlendFunc(srcRGB))
4567 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004568 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004569 return false;
4570 }
4571
4572 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4573 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004574 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004575 return false;
4576 }
4577
4578 if (!ValidSrcBlendFunc(srcAlpha))
4579 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004580 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004581 return false;
4582 }
4583
4584 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
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
Frank Henigman146e8a12017-03-02 23:22:37 -05004590 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4591 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004592 {
4593 bool constantColorUsed =
4594 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4595 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4596
4597 bool constantAlphaUsed =
4598 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4599 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4600
4601 if (constantColorUsed && constantAlphaUsed)
4602 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004603 const char *msg;
4604 if (context->getExtensions().webglCompatibility)
4605 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004606 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004607 }
4608 else
4609 {
4610 msg =
4611 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4612 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4613 "implementation.";
4614 ERR() << msg;
4615 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004616 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004617 return false;
4618 }
4619 }
4620
4621 return true;
4622}
4623
Geoff Langc339c4e2016-11-29 10:37:36 -05004624bool ValidateGetString(Context *context, GLenum name)
4625{
4626 switch (name)
4627 {
4628 case GL_VENDOR:
4629 case GL_RENDERER:
4630 case GL_VERSION:
4631 case GL_SHADING_LANGUAGE_VERSION:
4632 case GL_EXTENSIONS:
4633 break;
4634
4635 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4636 if (!context->getExtensions().requestExtension)
4637 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004638 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004639 return false;
4640 }
4641 break;
4642
4643 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004644 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004645 return false;
4646 }
4647
4648 return true;
4649}
4650
Geoff Lang47c48082016-12-07 15:38:13 -05004651bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4652{
4653 if (width <= 0.0f || isNaN(width))
4654 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004655 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004656 return false;
4657 }
4658
4659 return true;
4660}
4661
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004662bool ValidateVertexAttribPointer(ValidationContext *context,
4663 GLuint index,
4664 GLint size,
4665 GLenum type,
4666 GLboolean normalized,
4667 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004668 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004669{
Shao80957d92017-02-20 21:25:59 +08004670 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004671 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004672 return false;
4673 }
4674
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004675 if (stride < 0)
4676 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004677 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004678 return false;
4679 }
4680
Shao80957d92017-02-20 21:25:59 +08004681 const Caps &caps = context->getCaps();
4682 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004683 {
Shao80957d92017-02-20 21:25:59 +08004684 if (stride > caps.maxVertexAttribStride)
4685 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004686 context->handleError(InvalidValue()
4687 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004688 return false;
4689 }
4690
4691 if (index >= caps.maxVertexAttribBindings)
4692 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004693 context->handleError(InvalidValue()
4694 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004695 return false;
4696 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004697 }
4698
4699 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4700 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4701 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4702 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004703 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4704 context->getGLState().getVertexArray()->id() == 0;
Shao80957d92017-02-20 21:25:59 +08004705 if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004706 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004707 context
4708 ->handleError(InvalidOperation()
4709 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004710 return false;
4711 }
4712
4713 if (context->getExtensions().webglCompatibility)
4714 {
4715 // WebGL 1.0 [Section 6.14] Fixed point support
4716 // The WebGL API does not support the GL_FIXED data type.
4717 if (type == GL_FIXED)
4718 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004719 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004720 return false;
4721 }
4722
Geoff Lang2d62ab72017-03-23 16:54:40 -04004723 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004724 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 return false;
4726 }
4727 }
4728
4729 return true;
4730}
4731
Jamie Madill876429b2017-04-20 15:46:24 -04004732bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004733{
4734 if (context->getExtensions().webglCompatibility && zNear > zFar)
4735 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004736 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004737 return false;
4738 }
4739
4740 return true;
4741}
4742
Jamie Madille8fb6402017-02-14 17:56:40 -05004743bool ValidateRenderbufferStorage(ValidationContext *context,
4744 GLenum target,
4745 GLenum internalformat,
4746 GLsizei width,
4747 GLsizei height)
4748{
4749 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4750 height);
4751}
4752
4753bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4754 GLenum target,
4755 GLsizei samples,
4756 GLenum internalformat,
4757 GLsizei width,
4758 GLsizei height)
4759{
4760 if (!context->getExtensions().framebufferMultisample)
4761 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004762 context->handleError(InvalidOperation()
4763 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004764 return false;
4765 }
4766
4767 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4768 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4769 // generated.
4770 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4771 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004772 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004773 return false;
4774 }
4775
4776 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4777 // the specified storage. This is different than ES 3.0 in which a sample number higher
4778 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4779 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4780 if (context->getClientMajorVersion() >= 3)
4781 {
4782 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4783 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004785 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004786 return false;
4787 }
4788 }
4789
4790 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4791 width, height);
4792}
4793
Jamie Madillc1d770e2017-04-13 17:31:24 -04004794bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4795{
4796 if (!ValidFramebufferTarget(target))
4797 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004798 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004799 return false;
4800 }
4801
4802 return true;
4803}
4804
4805bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004806 GLfloat red,
4807 GLfloat green,
4808 GLfloat blue,
4809 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004810{
4811 return true;
4812}
4813
Jamie Madill876429b2017-04-20 15:46:24 -04004814bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004815{
4816 return true;
4817}
4818
4819bool ValidateClearStencil(ValidationContext *context, GLint s)
4820{
4821 return true;
4822}
4823
4824bool ValidateColorMask(ValidationContext *context,
4825 GLboolean red,
4826 GLboolean green,
4827 GLboolean blue,
4828 GLboolean alpha)
4829{
4830 return true;
4831}
4832
4833bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4834{
4835 return true;
4836}
4837
4838bool ValidateCreateProgram(ValidationContext *context)
4839{
4840 return true;
4841}
4842
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004843bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004844{
4845 switch (mode)
4846 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004847 case CullFaceMode::Front:
4848 case CullFaceMode::Back:
4849 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004850 break;
4851
4852 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004853 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854 return false;
4855 }
4856
4857 return true;
4858}
4859
4860bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4861{
4862 if (program == 0)
4863 {
4864 return false;
4865 }
4866
4867 if (!context->getProgram(program))
4868 {
4869 if (context->getShader(program))
4870 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004871 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872 return false;
4873 }
4874 else
4875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004876 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877 return false;
4878 }
4879 }
4880
4881 return true;
4882}
4883
4884bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4885{
4886 if (shader == 0)
4887 {
4888 return false;
4889 }
4890
4891 if (!context->getShader(shader))
4892 {
4893 if (context->getProgram(shader))
4894 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004895 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896 return false;
4897 }
4898 else
4899 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004900 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901 return false;
4902 }
4903 }
4904
4905 return true;
4906}
4907
4908bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4909{
4910 switch (func)
4911 {
4912 case GL_NEVER:
4913 case GL_ALWAYS:
4914 case GL_LESS:
4915 case GL_LEQUAL:
4916 case GL_EQUAL:
4917 case GL_GREATER:
4918 case GL_GEQUAL:
4919 case GL_NOTEQUAL:
4920 break;
4921
4922 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004923 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004924 return false;
4925 }
4926
4927 return true;
4928}
4929
4930bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4931{
4932 return true;
4933}
4934
4935bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4936{
4937 Program *programObject = GetValidProgram(context, program);
4938 if (!programObject)
4939 {
4940 return false;
4941 }
4942
4943 Shader *shaderObject = GetValidShader(context, shader);
4944 if (!shaderObject)
4945 {
4946 return false;
4947 }
4948
4949 const Shader *attachedShader = nullptr;
4950
4951 switch (shaderObject->getType())
4952 {
4953 case GL_VERTEX_SHADER:
4954 {
4955 attachedShader = programObject->getAttachedVertexShader();
4956 break;
4957 }
4958 case GL_FRAGMENT_SHADER:
4959 {
4960 attachedShader = programObject->getAttachedFragmentShader();
4961 break;
4962 }
4963 case GL_COMPUTE_SHADER:
4964 {
4965 attachedShader = programObject->getAttachedComputeShader();
4966 break;
4967 }
4968 default:
4969 UNREACHABLE();
4970 return false;
4971 }
4972
4973 if (attachedShader != shaderObject)
4974 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004975 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976 return false;
4977 }
4978
4979 return true;
4980}
4981
4982bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
4983{
4984 if (index >= MAX_VERTEX_ATTRIBS)
4985 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004986 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004987 return false;
4988 }
4989
4990 return true;
4991}
4992
4993bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
4994{
4995 if (index >= MAX_VERTEX_ATTRIBS)
4996 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004997 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004998 return false;
4999 }
5000
5001 return true;
5002}
5003
5004bool ValidateFinish(ValidationContext *context)
5005{
5006 return true;
5007}
5008
5009bool ValidateFlush(ValidationContext *context)
5010{
5011 return true;
5012}
5013
5014bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5015{
5016 switch (mode)
5017 {
5018 case GL_CW:
5019 case GL_CCW:
5020 break;
5021 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005022 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005023 return false;
5024 }
5025
5026 return true;
5027}
5028
5029bool ValidateGetActiveAttrib(ValidationContext *context,
5030 GLuint program,
5031 GLuint index,
5032 GLsizei bufsize,
5033 GLsizei *length,
5034 GLint *size,
5035 GLenum *type,
5036 GLchar *name)
5037{
5038 if (bufsize < 0)
5039 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005040 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005041 return false;
5042 }
5043
5044 Program *programObject = GetValidProgram(context, program);
5045
5046 if (!programObject)
5047 {
5048 return false;
5049 }
5050
5051 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5052 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005053 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005054 return false;
5055 }
5056
5057 return true;
5058}
5059
5060bool ValidateGetActiveUniform(ValidationContext *context,
5061 GLuint program,
5062 GLuint index,
5063 GLsizei bufsize,
5064 GLsizei *length,
5065 GLint *size,
5066 GLenum *type,
5067 GLchar *name)
5068{
5069 if (bufsize < 0)
5070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005071 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005072 return false;
5073 }
5074
5075 Program *programObject = GetValidProgram(context, program);
5076
5077 if (!programObject)
5078 {
5079 return false;
5080 }
5081
5082 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5083 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005084 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005085 return false;
5086 }
5087
5088 return true;
5089}
5090
5091bool ValidateGetAttachedShaders(ValidationContext *context,
5092 GLuint program,
5093 GLsizei maxcount,
5094 GLsizei *count,
5095 GLuint *shaders)
5096{
5097 if (maxcount < 0)
5098 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005099 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100 return false;
5101 }
5102
5103 Program *programObject = GetValidProgram(context, program);
5104
5105 if (!programObject)
5106 {
5107 return false;
5108 }
5109
5110 return true;
5111}
5112
5113bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5114{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005115 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5116 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005117 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005119 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005120 return false;
5121 }
5122
Jamie Madillc1d770e2017-04-13 17:31:24 -04005123 Program *programObject = GetValidProgram(context, program);
5124
5125 if (!programObject)
5126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005128 return false;
5129 }
5130
5131 if (!programObject->isLinked())
5132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005133 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005134 return false;
5135 }
5136
5137 return true;
5138}
5139
5140bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5141{
5142 GLenum nativeType;
5143 unsigned int numParams = 0;
5144 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5145}
5146
5147bool ValidateGetError(ValidationContext *context)
5148{
5149 return true;
5150}
5151
5152bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5153{
5154 GLenum nativeType;
5155 unsigned int numParams = 0;
5156 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5157}
5158
5159bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5160{
5161 GLenum nativeType;
5162 unsigned int numParams = 0;
5163 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5164}
5165
5166bool ValidateGetProgramInfoLog(ValidationContext *context,
5167 GLuint program,
5168 GLsizei bufsize,
5169 GLsizei *length,
5170 GLchar *infolog)
5171{
5172 if (bufsize < 0)
5173 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005174 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175 return false;
5176 }
5177
5178 Program *programObject = GetValidProgram(context, program);
5179 if (!programObject)
5180 {
5181 return false;
5182 }
5183
5184 return true;
5185}
5186
5187bool ValidateGetShaderInfoLog(ValidationContext *context,
5188 GLuint shader,
5189 GLsizei bufsize,
5190 GLsizei *length,
5191 GLchar *infolog)
5192{
5193 if (bufsize < 0)
5194 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005195 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005196 return false;
5197 }
5198
5199 Shader *shaderObject = GetValidShader(context, shader);
5200 if (!shaderObject)
5201 {
5202 return false;
5203 }
5204
5205 return true;
5206}
5207
5208bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5209 GLenum shadertype,
5210 GLenum precisiontype,
5211 GLint *range,
5212 GLint *precision)
5213{
5214 switch (shadertype)
5215 {
5216 case GL_VERTEX_SHADER:
5217 case GL_FRAGMENT_SHADER:
5218 break;
5219 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005220 context->handleError(InvalidOperation()
5221 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005222 return false;
5223 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005224 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005225 return false;
5226 }
5227
5228 switch (precisiontype)
5229 {
5230 case GL_LOW_FLOAT:
5231 case GL_MEDIUM_FLOAT:
5232 case GL_HIGH_FLOAT:
5233 case GL_LOW_INT:
5234 case GL_MEDIUM_INT:
5235 case GL_HIGH_INT:
5236 break;
5237
5238 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005239 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005240 return false;
5241 }
5242
5243 return true;
5244}
5245
5246bool ValidateGetShaderSource(ValidationContext *context,
5247 GLuint shader,
5248 GLsizei bufsize,
5249 GLsizei *length,
5250 GLchar *source)
5251{
5252 if (bufsize < 0)
5253 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005254 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005255 return false;
5256 }
5257
5258 Shader *shaderObject = GetValidShader(context, shader);
5259 if (!shaderObject)
5260 {
5261 return false;
5262 }
5263
5264 return true;
5265}
5266
5267bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5268{
5269 if (strstr(name, "gl_") == name)
5270 {
5271 return false;
5272 }
5273
Geoff Langfc32e8b2017-05-31 14:16:59 -04005274 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5275 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005276 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005278 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005279 return false;
5280 }
5281
Jamie Madillc1d770e2017-04-13 17:31:24 -04005282 Program *programObject = GetValidProgram(context, program);
5283
5284 if (!programObject)
5285 {
5286 return false;
5287 }
5288
5289 if (!programObject->isLinked())
5290 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005292 return false;
5293 }
5294
5295 return true;
5296}
5297
5298bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5299{
5300 switch (mode)
5301 {
5302 case GL_FASTEST:
5303 case GL_NICEST:
5304 case GL_DONT_CARE:
5305 break;
5306
5307 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005308 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 return false;
5310 }
5311
5312 switch (target)
5313 {
5314 case GL_GENERATE_MIPMAP_HINT:
5315 break;
5316
Geoff Lange7bd2182017-06-16 16:13:13 -04005317 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5318 if (context->getClientVersion() < ES_3_0 &&
5319 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005321 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005322 return false;
5323 }
5324 break;
5325
5326 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005327 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005328 return false;
5329 }
5330
5331 return true;
5332}
5333
5334bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5335{
5336 return true;
5337}
5338
5339bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5340{
5341 return true;
5342}
5343
5344bool ValidateIsProgram(ValidationContext *context, GLuint program)
5345{
5346 return true;
5347}
5348
5349bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5350{
5351 return true;
5352}
5353
5354bool ValidateIsShader(ValidationContext *context, GLuint shader)
5355{
5356 return true;
5357}
5358
5359bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5360{
5361 return true;
5362}
5363
5364bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5365{
5366 if (context->getClientMajorVersion() < 3)
5367 {
5368 switch (pname)
5369 {
5370 case GL_UNPACK_IMAGE_HEIGHT:
5371 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005372 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005373 return false;
5374
5375 case GL_UNPACK_ROW_LENGTH:
5376 case GL_UNPACK_SKIP_ROWS:
5377 case GL_UNPACK_SKIP_PIXELS:
5378 if (!context->getExtensions().unpackSubimage)
5379 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005380 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005381 return false;
5382 }
5383 break;
5384
5385 case GL_PACK_ROW_LENGTH:
5386 case GL_PACK_SKIP_ROWS:
5387 case GL_PACK_SKIP_PIXELS:
5388 if (!context->getExtensions().packSubimage)
5389 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005390 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005391 return false;
5392 }
5393 break;
5394 }
5395 }
5396
5397 if (param < 0)
5398 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005399 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005400 return false;
5401 }
5402
5403 switch (pname)
5404 {
5405 case GL_UNPACK_ALIGNMENT:
5406 if (param != 1 && param != 2 && param != 4 && param != 8)
5407 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005408 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409 return false;
5410 }
5411 break;
5412
5413 case GL_PACK_ALIGNMENT:
5414 if (param != 1 && param != 2 && param != 4 && param != 8)
5415 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005416 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005417 return false;
5418 }
5419 break;
5420
5421 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005422 if (!context->getExtensions().packReverseRowOrder)
5423 {
5424 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5425 }
5426 break;
5427
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 case GL_UNPACK_ROW_LENGTH:
5429 case GL_UNPACK_IMAGE_HEIGHT:
5430 case GL_UNPACK_SKIP_IMAGES:
5431 case GL_UNPACK_SKIP_ROWS:
5432 case GL_UNPACK_SKIP_PIXELS:
5433 case GL_PACK_ROW_LENGTH:
5434 case GL_PACK_SKIP_ROWS:
5435 case GL_PACK_SKIP_PIXELS:
5436 break;
5437
5438 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005439 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005440 return false;
5441 }
5442
5443 return true;
5444}
5445
5446bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5447{
5448 return true;
5449}
5450
5451bool ValidateReleaseShaderCompiler(ValidationContext *context)
5452{
5453 return true;
5454}
5455
Jamie Madill876429b2017-04-20 15:46:24 -04005456bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005457{
5458 return true;
5459}
5460
5461bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5462{
5463 if (width < 0 || height < 0)
5464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005465 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005466 return false;
5467 }
5468
5469 return true;
5470}
5471
5472bool ValidateShaderBinary(ValidationContext *context,
5473 GLsizei n,
5474 const GLuint *shaders,
5475 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005476 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005477 GLsizei length)
5478{
5479 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5480 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5481 shaderBinaryFormats.end())
5482 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005483 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484 return false;
5485 }
5486
5487 return true;
5488}
5489
5490bool ValidateShaderSource(ValidationContext *context,
5491 GLuint shader,
5492 GLsizei count,
5493 const GLchar *const *string,
5494 const GLint *length)
5495{
5496 if (count < 0)
5497 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005498 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005499 return false;
5500 }
5501
Geoff Langfc32e8b2017-05-31 14:16:59 -04005502 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5503 // shader-related entry points
5504 if (context->getExtensions().webglCompatibility)
5505 {
5506 for (GLsizei i = 0; i < count; i++)
5507 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005508 size_t len =
5509 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005510
5511 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005512 if (!IsValidESSLShaderSourceString(string[i], len,
5513 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005514 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005515 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005516 return false;
5517 }
5518 }
5519 }
5520
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521 Shader *shaderObject = GetValidShader(context, shader);
5522 if (!shaderObject)
5523 {
5524 return false;
5525 }
5526
5527 return true;
5528}
5529
5530bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5531{
5532 if (!IsValidStencilFunc(func))
5533 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005534 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535 return false;
5536 }
5537
5538 return true;
5539}
5540
5541bool ValidateStencilFuncSeparate(ValidationContext *context,
5542 GLenum face,
5543 GLenum func,
5544 GLint ref,
5545 GLuint mask)
5546{
5547 if (!IsValidStencilFace(face))
5548 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005549 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005550 return false;
5551 }
5552
5553 if (!IsValidStencilFunc(func))
5554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 return false;
5557 }
5558
5559 return true;
5560}
5561
5562bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5563{
5564 return true;
5565}
5566
5567bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5568{
5569 if (!IsValidStencilFace(face))
5570 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005571 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005572 return false;
5573 }
5574
5575 return true;
5576}
5577
5578bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5579{
5580 if (!IsValidStencilOp(fail))
5581 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005583 return false;
5584 }
5585
5586 if (!IsValidStencilOp(zfail))
5587 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005588 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005589 return false;
5590 }
5591
5592 if (!IsValidStencilOp(zpass))
5593 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005594 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005595 return false;
5596 }
5597
5598 return true;
5599}
5600
5601bool ValidateStencilOpSeparate(ValidationContext *context,
5602 GLenum face,
5603 GLenum fail,
5604 GLenum zfail,
5605 GLenum zpass)
5606{
5607 if (!IsValidStencilFace(face))
5608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610 return false;
5611 }
5612
5613 return ValidateStencilOp(context, fail, zfail, zpass);
5614}
5615
5616bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5617{
5618 return ValidateUniform(context, GL_FLOAT, location, 1);
5619}
5620
5621bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5622{
5623 return ValidateUniform(context, GL_FLOAT, location, count);
5624}
5625
Jamie Madillbe849e42017-05-02 15:49:00 -04005626bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5627{
5628 return ValidateUniform1iv(context, location, 1, &x);
5629}
5630
Jamie Madillc1d770e2017-04-13 17:31:24 -04005631bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5632{
5633 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5634}
5635
5636bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5637{
5638 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5639}
5640
5641bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5642{
5643 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5644}
5645
5646bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5647{
5648 return ValidateUniform(context, GL_INT_VEC2, location, count);
5649}
5650
5651bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5652{
5653 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5654}
5655
5656bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5657{
5658 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5659}
5660
5661bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5662{
5663 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5664}
5665
5666bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5667{
5668 return ValidateUniform(context, GL_INT_VEC3, location, count);
5669}
5670
5671bool ValidateUniform4f(ValidationContext *context,
5672 GLint location,
5673 GLfloat x,
5674 GLfloat y,
5675 GLfloat z,
5676 GLfloat w)
5677{
5678 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5679}
5680
5681bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5682{
5683 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5684}
5685
5686bool ValidateUniform4i(ValidationContext *context,
5687 GLint location,
5688 GLint x,
5689 GLint y,
5690 GLint z,
5691 GLint w)
5692{
5693 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5694}
5695
5696bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5697{
5698 return ValidateUniform(context, GL_INT_VEC4, location, count);
5699}
5700
5701bool ValidateUniformMatrix2fv(ValidationContext *context,
5702 GLint location,
5703 GLsizei count,
5704 GLboolean transpose,
5705 const GLfloat *value)
5706{
5707 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5708}
5709
5710bool ValidateUniformMatrix3fv(ValidationContext *context,
5711 GLint location,
5712 GLsizei count,
5713 GLboolean transpose,
5714 const GLfloat *value)
5715{
5716 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5717}
5718
5719bool ValidateUniformMatrix4fv(ValidationContext *context,
5720 GLint location,
5721 GLsizei count,
5722 GLboolean transpose,
5723 const GLfloat *value)
5724{
5725 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5726}
5727
5728bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5729{
5730 Program *programObject = GetValidProgram(context, program);
5731
5732 if (!programObject)
5733 {
5734 return false;
5735 }
5736
5737 return true;
5738}
5739
Jamie Madillc1d770e2017-04-13 17:31:24 -04005740bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5741{
5742 return ValidateVertexAttribIndex(context, index);
5743}
5744
5745bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5746{
5747 return ValidateVertexAttribIndex(context, index);
5748}
5749
5750bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5751{
5752 return ValidateVertexAttribIndex(context, index);
5753}
5754
5755bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5756{
5757 return ValidateVertexAttribIndex(context, index);
5758}
5759
5760bool ValidateVertexAttrib3f(ValidationContext *context,
5761 GLuint index,
5762 GLfloat x,
5763 GLfloat y,
5764 GLfloat z)
5765{
5766 return ValidateVertexAttribIndex(context, index);
5767}
5768
5769bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5770{
5771 return ValidateVertexAttribIndex(context, index);
5772}
5773
5774bool ValidateVertexAttrib4f(ValidationContext *context,
5775 GLuint index,
5776 GLfloat x,
5777 GLfloat y,
5778 GLfloat z,
5779 GLfloat w)
5780{
5781 return ValidateVertexAttribIndex(context, index);
5782}
5783
5784bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5785{
5786 return ValidateVertexAttribIndex(context, index);
5787}
5788
5789bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5790{
5791 if (width < 0 || height < 0)
5792 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005793 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794 return false;
5795 }
5796
5797 return true;
5798}
5799
5800bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5801{
5802 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5803}
5804
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005805bool ValidateDrawElements(ValidationContext *context,
5806 GLenum mode,
5807 GLsizei count,
5808 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005809 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005810{
5811 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5812}
5813
Jamie Madillbe849e42017-05-02 15:49:00 -04005814bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
5815 GLenum target,
5816 GLenum attachment,
5817 GLenum pname,
5818 GLint *params)
5819{
5820 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5821 nullptr);
5822}
5823
5824bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5825{
5826 return ValidateGetProgramivBase(context, program, pname, nullptr);
5827}
5828
5829bool ValidateCopyTexImage2D(ValidationContext *context,
5830 GLenum target,
5831 GLint level,
5832 GLenum internalformat,
5833 GLint x,
5834 GLint y,
5835 GLsizei width,
5836 GLsizei height,
5837 GLint border)
5838{
5839 if (context->getClientMajorVersion() < 3)
5840 {
5841 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5842 0, x, y, width, height, border);
5843 }
5844
5845 ASSERT(context->getClientMajorVersion() == 3);
5846 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5847 0, x, y, width, height, border);
5848}
5849
5850bool ValidateCopyTexSubImage2D(Context *context,
5851 GLenum target,
5852 GLint level,
5853 GLint xoffset,
5854 GLint yoffset,
5855 GLint x,
5856 GLint y,
5857 GLsizei width,
5858 GLsizei height)
5859{
5860 if (context->getClientMajorVersion() < 3)
5861 {
5862 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5863 yoffset, x, y, width, height, 0);
5864 }
5865
5866 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5867 yoffset, 0, x, y, width, height, 0);
5868}
5869
5870bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5871{
5872 return ValidateGenOrDelete(context, n);
5873}
5874
5875bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5876{
5877 return ValidateGenOrDelete(context, n);
5878}
5879
5880bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5881{
5882 return ValidateGenOrDelete(context, n);
5883}
5884
5885bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5886{
5887 return ValidateGenOrDelete(context, n);
5888}
5889
5890bool ValidateDisable(Context *context, GLenum cap)
5891{
5892 if (!ValidCap(context, cap, false))
5893 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005894 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005895 return false;
5896 }
5897
5898 return true;
5899}
5900
5901bool ValidateEnable(Context *context, GLenum cap)
5902{
5903 if (!ValidCap(context, cap, false))
5904 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005905 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005906 return false;
5907 }
5908
5909 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5910 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5911 {
5912 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005913 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005914
5915 // We also output an error message to the debugger window if tracing is active, so that
5916 // developers can see the error message.
5917 ERR() << errorMessage;
5918 return false;
5919 }
5920
5921 return true;
5922}
5923
5924bool ValidateFramebufferRenderbuffer(Context *context,
5925 GLenum target,
5926 GLenum attachment,
5927 GLenum renderbuffertarget,
5928 GLuint renderbuffer)
5929{
Brandon Jones6cad5662017-06-14 13:25:13 -07005930 if (!ValidFramebufferTarget(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5933 return false;
5934 }
5935
5936 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5937 {
5938 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005939 return false;
5940 }
5941
5942 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5943 renderbuffertarget, renderbuffer);
5944}
5945
5946bool ValidateFramebufferTexture2D(Context *context,
5947 GLenum target,
5948 GLenum attachment,
5949 GLenum textarget,
5950 GLuint texture,
5951 GLint level)
5952{
5953 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5954 // extension
5955 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5956 level != 0)
5957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005958 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 return false;
5960 }
5961
5962 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5963 {
5964 return false;
5965 }
5966
5967 if (texture != 0)
5968 {
5969 gl::Texture *tex = context->getTexture(texture);
5970 ASSERT(tex);
5971
5972 const gl::Caps &caps = context->getCaps();
5973
5974 switch (textarget)
5975 {
5976 case GL_TEXTURE_2D:
5977 {
5978 if (level > gl::log2(caps.max2DTextureSize))
5979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005980 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 return false;
5982 }
5983 if (tex->getTarget() != GL_TEXTURE_2D)
5984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005985 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 return false;
5987 }
5988 }
5989 break;
5990
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005991 case GL_TEXTURE_RECTANGLE_ANGLE:
5992 {
5993 if (level != 0)
5994 {
5995 context->handleError(InvalidValue());
5996 return false;
5997 }
5998 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
5999 {
6000 context->handleError(InvalidOperation()
6001 << "Textarget must match the texture target type.");
6002 return false;
6003 }
6004 }
6005 break;
6006
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
6008 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
6009 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
6010 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
6011 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
6012 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
6013 {
6014 if (level > gl::log2(caps.maxCubeMapTextureSize))
6015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006016 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006017 return false;
6018 }
6019 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
6020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006021 context->handleError(InvalidOperation()
6022 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006023 return false;
6024 }
6025 }
6026 break;
6027
6028 case GL_TEXTURE_2D_MULTISAMPLE:
6029 {
6030 if (context->getClientVersion() < ES_3_1)
6031 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006032 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 return false;
6034 }
6035
6036 if (level != 0)
6037 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006038 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 return false;
6040 }
6041 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
6042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006043 context->handleError(InvalidOperation()
6044 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
6047 }
6048 break;
6049
6050 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006051 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006052 return false;
6053 }
6054
6055 const Format &format = tex->getFormat(textarget, level);
6056 if (format.info->compressed)
6057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006058 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006059 return false;
6060 }
6061 }
6062
6063 return true;
6064}
6065
6066bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6067{
6068 return ValidateGenOrDelete(context, n);
6069}
6070
6071bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6072{
6073 return ValidateGenOrDelete(context, n);
6074}
6075
6076bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6077{
6078 return ValidateGenOrDelete(context, n);
6079}
6080
6081bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6082{
6083 return ValidateGenOrDelete(context, n);
6084}
6085
6086bool ValidateGenerateMipmap(Context *context, GLenum target)
6087{
6088 if (!ValidTextureTarget(context, target))
6089 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006090 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006091 return false;
6092 }
6093
6094 Texture *texture = context->getTargetTexture(target);
6095
6096 if (texture == nullptr)
6097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006098 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006099 return false;
6100 }
6101
6102 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6103
6104 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6105 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6106 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006108 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006109 return false;
6110 }
6111
6112 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
Geoff Lang536eca12017-09-13 11:23:35 -04006113 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6114 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6115 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006116 {
6117 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6118 return false;
6119 }
6120
Geoff Lang536eca12017-09-13 11:23:35 -04006121 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6122 bool formatUnsized = !format.sized;
6123 bool formatColorRenderableAndFilterable =
6124 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6125 format.renderSupport(context->getClientVersion(), context->getExtensions());
6126 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 {
Geoff Lang536eca12017-09-13 11:23:35 -04006128 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006129 return false;
6130 }
6131
Geoff Lang536eca12017-09-13 11:23:35 -04006132 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6133 // generation
6134 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6135 {
6136 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6137 return false;
6138 }
6139
6140 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6141 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006142 bool supportsSRGBMipmapGeneration =
6143 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006144 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 {
Geoff Lang536eca12017-09-13 11:23:35 -04006146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006147 return false;
6148 }
6149
6150 // Non-power of 2 ES2 check
6151 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6152 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6153 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6154 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006155 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6156 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 return false;
6159 }
6160
6161 // Cube completeness check
6162 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 return false;
6166 }
6167
6168 return true;
6169}
6170
6171bool ValidateGetBufferParameteriv(ValidationContext *context,
6172 GLenum target,
6173 GLenum pname,
6174 GLint *params)
6175{
6176 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6177}
6178
6179bool ValidateGetRenderbufferParameteriv(Context *context,
6180 GLenum target,
6181 GLenum pname,
6182 GLint *params)
6183{
6184 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6185}
6186
6187bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6188{
6189 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6190}
6191
6192bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6193{
6194 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6195}
6196
6197bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6198{
6199 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6200}
6201
6202bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6203{
6204 return ValidateGetUniformBase(context, program, location);
6205}
6206
6207bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6208{
6209 return ValidateGetUniformBase(context, program, location);
6210}
6211
6212bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6213{
6214 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6215}
6216
6217bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6218{
6219 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6220}
6221
6222bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6223{
6224 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6225}
6226
6227bool ValidateIsEnabled(Context *context, GLenum cap)
6228{
6229 if (!ValidCap(context, cap, true))
6230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006231 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006232 return false;
6233 }
6234
6235 return true;
6236}
6237
6238bool ValidateLinkProgram(Context *context, GLuint program)
6239{
6240 if (context->hasActiveTransformFeedback(program))
6241 {
6242 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006243 context->handleError(InvalidOperation() << "Cannot link program while program is "
6244 "associated with an active transform "
6245 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006246 return false;
6247 }
6248
6249 Program *programObject = GetValidProgram(context, program);
6250 if (!programObject)
6251 {
6252 return false;
6253 }
6254
6255 return true;
6256}
6257
Jamie Madill4928b7c2017-06-20 12:57:39 -04006258bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006259 GLint x,
6260 GLint y,
6261 GLsizei width,
6262 GLsizei height,
6263 GLenum format,
6264 GLenum type,
6265 void *pixels)
6266{
6267 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6268 nullptr, pixels);
6269}
6270
6271bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6272{
6273 return ValidateTexParameterBase(context, target, pname, -1, &param);
6274}
6275
6276bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6277{
6278 return ValidateTexParameterBase(context, target, pname, -1, params);
6279}
6280
6281bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6282{
6283 return ValidateTexParameterBase(context, target, pname, -1, &param);
6284}
6285
6286bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6287{
6288 return ValidateTexParameterBase(context, target, pname, -1, params);
6289}
6290
6291bool ValidateUseProgram(Context *context, GLuint program)
6292{
6293 if (program != 0)
6294 {
6295 Program *programObject = context->getProgram(program);
6296 if (!programObject)
6297 {
6298 // ES 3.1.0 section 7.3 page 72
6299 if (context->getShader(program))
6300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006302 return false;
6303 }
6304 else
6305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006306 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006307 return false;
6308 }
6309 }
6310 if (!programObject->isLinked())
6311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006313 return false;
6314 }
6315 }
6316 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6317 {
6318 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006319 context
6320 ->handleError(InvalidOperation()
6321 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006322 return false;
6323 }
6324
6325 return true;
6326}
6327
Jamie Madillc29968b2016-01-20 11:17:23 -05006328} // namespace gl