blob: 6cdf832a15a71205c6506c2289d9697585760842 [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
Jamie Madill778bf092018-11-14 09:54:36 -05009#include "libANGLE/validationES2_autogen.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
Jamie Madill778bf092018-11-14 09:54:36 -050028#include "libANGLE/validationES2.h"
29#include "libANGLE/validationES3_autogen.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040030
31namespace gl
32{
Jamie Madille0472f32018-11-27 16:32:45 -050033using namespace err;
Geoff Lange8ebe7f2013-08-05 15:03:13 -040034
Jamie Madillc29968b2016-01-20 11:17:23 -050035namespace
36{
37
38bool IsPartialBlit(gl::Context *context,
39 const FramebufferAttachment *readBuffer,
40 const FramebufferAttachment *writeBuffer,
41 GLint srcX0,
42 GLint srcY0,
43 GLint srcX1,
44 GLint srcY1,
45 GLint dstX0,
46 GLint dstY0,
47 GLint dstX1,
48 GLint dstY1)
49{
50 const Extents &writeSize = writeBuffer->getSize();
51 const Extents &readSize = readBuffer->getSize();
52
53 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
54 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
55 {
56 return true;
57 }
58
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070061 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050062 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
63 scissor.height < writeSize.height;
64 }
65
66 return false;
67}
68
Sami Väisänend59ca052016-06-21 16:10:00 +030069template <typename T>
70bool ValidatePathInstances(gl::Context *context,
71 GLsizei numPaths,
72 const void *paths,
73 GLuint pathBase)
74{
75 const auto *array = static_cast<const T *>(paths);
76
77 for (GLsizei i = 0; i < numPaths; ++i)
78 {
79 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070080 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030081 {
Jamie Madille0472f32018-11-27 16:32:45 -050082 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030083 return false;
84 }
85 }
86 return true;
87}
88
89bool ValidateInstancedPathParameters(gl::Context *context,
90 GLsizei numPaths,
91 GLenum pathNameType,
92 const void *paths,
93 GLuint pathBase,
94 GLenum transformType,
95 const GLfloat *transformValues)
96{
97 if (!context->getExtensions().pathRendering)
98 {
Jamie Madill610640f2018-11-21 17:28:41 -050099 context->validationError(GL_INVALID_OPERATION,
100 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300101 return false;
102 }
103
104 if (paths == nullptr)
105 {
Jamie Madill610640f2018-11-21 17:28:41 -0500106 context->validationError(GL_INVALID_VALUE, "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300107 return false;
108 }
109
110 if (numPaths < 0)
111 {
Jamie Madill610640f2018-11-21 17:28:41 -0500112 context->validationError(GL_INVALID_VALUE, "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300113 return false;
114 }
115
116 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
117 {
Jamie Madille0472f32018-11-27 16:32:45 -0500118 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300119 return false;
120 }
121
122 std::uint32_t pathNameTypeSize = 0;
123 std::uint32_t componentCount = 0;
124
125 switch (pathNameType)
126 {
127 case GL_UNSIGNED_BYTE:
128 pathNameTypeSize = sizeof(GLubyte);
129 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
130 return false;
131 break;
132
133 case GL_BYTE:
134 pathNameTypeSize = sizeof(GLbyte);
135 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
136 return false;
137 break;
138
139 case GL_UNSIGNED_SHORT:
140 pathNameTypeSize = sizeof(GLushort);
141 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
142 return false;
143 break;
144
145 case GL_SHORT:
146 pathNameTypeSize = sizeof(GLshort);
147 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
148 return false;
149 break;
150
151 case GL_UNSIGNED_INT:
152 pathNameTypeSize = sizeof(GLuint);
153 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
154 return false;
155 break;
156
157 case GL_INT:
158 pathNameTypeSize = sizeof(GLint);
159 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
160 return false;
161 break;
162
163 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500164 context->validationError(GL_INVALID_ENUM, "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300165 return false;
166 }
167
168 switch (transformType)
169 {
170 case GL_NONE:
171 componentCount = 0;
172 break;
173 case GL_TRANSLATE_X_CHROMIUM:
174 case GL_TRANSLATE_Y_CHROMIUM:
175 componentCount = 1;
176 break;
177 case GL_TRANSLATE_2D_CHROMIUM:
178 componentCount = 2;
179 break;
180 case GL_TRANSLATE_3D_CHROMIUM:
181 componentCount = 3;
182 break;
183 case GL_AFFINE_2D_CHROMIUM:
184 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
185 componentCount = 6;
186 break;
187 case GL_AFFINE_3D_CHROMIUM:
188 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
189 componentCount = 12;
190 break;
191 default:
Jamie Madill610640f2018-11-21 17:28:41 -0500192 context->validationError(GL_INVALID_ENUM, "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300193 return false;
194 }
195 if (componentCount != 0 && transformValues == nullptr)
196 {
Jamie Madill610640f2018-11-21 17:28:41 -0500197 context->validationError(GL_INVALID_VALUE, "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300198 return false;
199 }
200
201 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
202 checkedSize += (numPaths * pathNameTypeSize);
203 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
204 if (!checkedSize.IsValid())
205 {
Jamie Madille0472f32018-11-27 16:32:45 -0500206 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300207 return false;
208 }
209
210 return true;
211}
212
Geoff Lang4f0e0032017-05-01 16:04:35 -0400213bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700214{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400216 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700217 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400218 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700219 case GL_ALPHA:
220 case GL_LUMINANCE:
221 case GL_LUMINANCE_ALPHA:
222 case GL_RGB:
223 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400224 case GL_RGB8:
225 case GL_RGBA8:
226 case GL_BGRA_EXT:
227 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700228 return true;
229
Geoff Lang4f0e0032017-05-01 16:04:35 -0400230 default:
231 return false;
232 }
233}
Geoff Lang97073d12016-04-20 10:42:34 -0700234
Geoff Lang4f0e0032017-05-01 16:04:35 -0400235bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
236{
237 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
238}
239
Geoff Lang4f0e0032017-05-01 16:04:35 -0400240bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
241{
242 // Table 1.0 from the CHROMIUM_copy_texture spec
243 switch (internalFormat)
244 {
245 case GL_RGB:
246 case GL_RGBA:
247 case GL_RGB8:
248 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700249 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400250 case GL_BGRA8_EXT:
251 case GL_SRGB_EXT:
252 case GL_SRGB_ALPHA_EXT:
253 case GL_R8:
254 case GL_R8UI:
255 case GL_RG8:
256 case GL_RG8UI:
257 case GL_SRGB8:
258 case GL_RGB565:
259 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400260 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400261 case GL_SRGB8_ALPHA8:
262 case GL_RGB5_A1:
263 case GL_RGBA4:
264 case GL_RGBA8UI:
265 case GL_RGB9_E5:
266 case GL_R16F:
267 case GL_R32F:
268 case GL_RG16F:
269 case GL_RG32F:
270 case GL_RGB16F:
271 case GL_RGB32F:
272 case GL_RGBA16F:
273 case GL_RGBA32F:
274 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700275 case GL_LUMINANCE:
276 case GL_LUMINANCE_ALPHA:
277 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400278 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700279
280 default:
281 return false;
282 }
283}
284
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400285bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
286{
287 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
288}
289
Geoff Lang97073d12016-04-20 10:42:34 -0700290bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
291{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400292 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700293 {
Jamie Madille0472f32018-11-27 16:32:45 -0500294 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400295 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700296 }
297
Geoff Langc0094ec2017-08-16 14:16:24 -0400298 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
299 {
Jamie Madille0472f32018-11-27 16:32:45 -0500300 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400301 return false;
302 }
303
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
305 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700306 {
Jamie Madille0472f32018-11-27 16:32:45 -0500307 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400308 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700309 }
310
311 return true;
312}
313
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700315{
316 switch (target)
317 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800318 case TextureTarget::_2D:
319 case TextureTarget::CubeMapNegativeX:
320 case TextureTarget::CubeMapNegativeY:
321 case TextureTarget::CubeMapNegativeZ:
322 case TextureTarget::CubeMapPositiveX:
323 case TextureTarget::CubeMapPositiveY:
324 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400325 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700326
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800327 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400328 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700329
330 default:
331 return false;
332 }
333}
334
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335bool IsValidCopyTextureDestinationTarget(Context *context,
336 TextureType textureType,
337 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400338{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800339 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400340}
341
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700343{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700345 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800346 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400347 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800348 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400349 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400350
Jamie Madillb980c562018-11-27 11:34:27 -0500351 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
352 // supported
Geoff Lang4f0e0032017-05-01 16:04:35 -0400353
354 default:
355 return false;
356 }
357}
358
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800359bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400360{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800361 if (!ValidMipLevel(context, type, 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,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800375 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376 GLint level,
377 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800378 GLsizei height,
379 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400380{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800381 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400382 {
383 return false;
384 }
385
Brandon Jones28783792018-03-05 09:37:32 -0800386 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
387 {
388 return false;
389 }
390
Geoff Lang4f0e0032017-05-01 16:04:35 -0400391 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800392 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400393 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800394 case TextureType::_2D:
395 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
396 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
397 case TextureType::Rectangle:
398 ASSERT(level == 0);
399 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
400 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400401
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800402 case TextureType::CubeMap:
403 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
404 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
405 default:
406 return true;
407 }
Geoff Lang97073d12016-04-20 10:42:34 -0700408}
409
Jamie Madillc1d770e2017-04-13 17:31:24 -0400410bool IsValidStencilFunc(GLenum func)
411{
412 switch (func)
413 {
414 case GL_NEVER:
415 case GL_ALWAYS:
416 case GL_LESS:
417 case GL_LEQUAL:
418 case GL_EQUAL:
419 case GL_GEQUAL:
420 case GL_GREATER:
421 case GL_NOTEQUAL:
422 return true;
423
424 default:
425 return false;
426 }
427}
428
429bool IsValidStencilFace(GLenum face)
430{
431 switch (face)
432 {
433 case GL_FRONT:
434 case GL_BACK:
435 case GL_FRONT_AND_BACK:
436 return true;
437
438 default:
439 return false;
440 }
441}
442
443bool IsValidStencilOp(GLenum op)
444{
445 switch (op)
446 {
447 case GL_ZERO:
448 case GL_KEEP:
449 case GL_REPLACE:
450 case GL_INCR:
451 case GL_DECR:
452 case GL_INVERT:
453 case GL_INCR_WRAP:
454 case GL_DECR_WRAP:
455 return true;
456
457 default:
458 return false;
459 }
460}
461
Jamie Madill5b772312018-03-08 20:28:32 -0500462bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800463 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400464 GLint level,
465 GLenum internalformat,
466 bool isSubImage,
467 GLint xoffset,
468 GLint yoffset,
469 GLint x,
470 GLint y,
471 GLsizei width,
472 GLsizei height,
473 GLint border)
474{
475 if (!ValidTexture2DDestinationTarget(context, target))
476 {
Jamie Madille0472f32018-11-27 16:32:45 -0500477 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400478 return false;
479 }
480
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800481 TextureType texType = TextureTargetToType(target);
482 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400483 {
Jamie Madill610640f2018-11-21 17:28:41 -0500484 context->validationError(GL_INVALID_VALUE, "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400485 return false;
486 }
487
488 Format textureFormat = Format::Invalid();
489 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
490 xoffset, yoffset, 0, x, y, width, height, border,
491 &textureFormat))
492 {
493 return false;
494 }
495
496 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
497 GLenum colorbufferFormat =
498 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
499 const auto &formatInfo = *textureFormat.info;
500
501 // [OpenGL ES 2.0.24] table 3.9
502 if (isSubImage)
503 {
504 switch (formatInfo.format)
505 {
506 case GL_ALPHA:
507 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400508 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
509 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400510 {
Jamie Madille0472f32018-11-27 16:32:45 -0500511 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400512 return false;
513 }
514 break;
515 case GL_LUMINANCE:
516 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
517 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
518 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400519 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
520 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400521 {
Jamie Madille0472f32018-11-27 16:32:45 -0500522 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400523 return false;
524 }
525 break;
526 case GL_RED_EXT:
527 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
528 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
529 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
530 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
531 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400532 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
533 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400534 {
Jamie Madille0472f32018-11-27 16:32:45 -0500535 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400536 return false;
537 }
538 break;
539 case GL_RG_EXT:
540 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
541 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
542 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
543 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400544 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
545 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400546 {
Jamie Madille0472f32018-11-27 16:32:45 -0500547 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400548 return false;
549 }
550 break;
551 case GL_RGB:
552 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
553 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
554 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400555 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
556 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400557 {
Jamie Madille0472f32018-11-27 16:32:45 -0500558 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400559 return false;
560 }
561 break;
562 case GL_LUMINANCE_ALPHA:
563 case GL_RGBA:
564 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400565 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
566 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400567 {
Jamie Madille0472f32018-11-27 16:32:45 -0500568 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400569 return false;
570 }
571 break;
572 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
573 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
574 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
575 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
576 case GL_ETC1_RGB8_OES:
577 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
578 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
579 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
580 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
581 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300582 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
583 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
584 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
585 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Jamie Madille0472f32018-11-27 16:32:45 -0500586 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400587 return false;
588 case GL_DEPTH_COMPONENT:
589 case GL_DEPTH_STENCIL_OES:
Jamie Madille0472f32018-11-27 16:32:45 -0500590 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500593 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400594 return false;
595 }
596
597 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
598 {
Jamie Madille0472f32018-11-27 16:32:45 -0500599 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500612 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500623 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500634 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500644 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500654 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500664 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500672 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400673 return false;
674 }
675 else
676 {
Jamie Madille0472f32018-11-27 16:32:45 -0500677 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500684 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400685 return false;
686 }
687 else
688 {
Jamie Madille0472f32018-11-27 16:32:45 -0500689 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500696 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400697 return false;
698 }
699 else
700 {
Jamie Madille0472f32018-11-27 16:32:45 -0500701 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500708 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400709 return false;
710 }
711 else
712 {
Jamie Madille0472f32018-11-27 16:32:45 -0500713 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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 {
Jamie Madill610640f2018-11-21 17:28:41 -0500724 context->validationError(GL_INVALID_OPERATION,
725 "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400726 return false;
727 }
728 else
729 {
Jamie Madill610640f2018-11-21 17:28:41 -0500730 context->validationError(GL_INVALID_ENUM,
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 {
Jamie Madille0472f32018-11-27 16:32:45 -0500742 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 else
746 {
Jamie Madille0472f32018-11-27 16:32:45 -0500747 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400748 return false;
749 }
750 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500751 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
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
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700803 // GLES1 emulation: GLES1-specific caps
804 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700805 case GL_VERTEX_ARRAY:
806 case GL_NORMAL_ARRAY:
807 case GL_COLOR_ARRAY:
808 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700809 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700810 case GL_LIGHTING:
811 case GL_LIGHT0:
812 case GL_LIGHT1:
813 case GL_LIGHT2:
814 case GL_LIGHT3:
815 case GL_LIGHT4:
816 case GL_LIGHT5:
817 case GL_LIGHT6:
818 case GL_LIGHT7:
819 case GL_NORMALIZE:
820 case GL_RESCALE_NORMAL:
821 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700822 case GL_CLIP_PLANE0:
823 case GL_CLIP_PLANE1:
824 case GL_CLIP_PLANE2:
825 case GL_CLIP_PLANE3:
826 case GL_CLIP_PLANE4:
827 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700828 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700829 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700830 case GL_LINE_SMOOTH:
831 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700832 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700833 case GL_POINT_SIZE_ARRAY_OES:
834 return context->getClientVersion() < Version(2, 0) &&
835 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700836 case GL_TEXTURE_CUBE_MAP:
837 return context->getClientVersion() < Version(2, 0) &&
838 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700839 case GL_POINT_SPRITE_OES:
840 return context->getClientVersion() < Version(2, 0) &&
841 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400842 default:
843 return false;
844 }
845}
846
Geoff Langfc32e8b2017-05-31 14:16:59 -0400847// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
848// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400849bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400850{
851 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400852 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
853 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400854 {
855 return true;
856 }
857
858 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
859 if (c >= 9 && c <= 13)
860 {
861 return true;
862 }
863
864 return false;
865}
866
Geoff Langcab92ee2017-07-19 17:32:07 -0400867bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400868{
Geoff Langa71a98e2017-06-19 15:15:00 -0400869 for (size_t i = 0; i < len; i++)
870 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400871 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400872 {
873 return false;
874 }
875 }
876
877 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400878}
879
Geoff Langcab92ee2017-07-19 17:32:07 -0400880bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
881{
882 enum class ParseState
883 {
884 // Have not seen an ASCII non-whitespace character yet on
885 // this line. Possible that we might see a preprocessor
886 // directive.
887 BEGINING_OF_LINE,
888
889 // Have seen at least one ASCII non-whitespace character
890 // on this line.
891 MIDDLE_OF_LINE,
892
893 // Handling a preprocessor directive. Passes through all
894 // characters up to the end of the line. Disables comment
895 // processing.
896 IN_PREPROCESSOR_DIRECTIVE,
897
898 // Handling a single-line comment. The comment text is
899 // replaced with a single space.
900 IN_SINGLE_LINE_COMMENT,
901
902 // Handling a multi-line comment. Newlines are passed
903 // through to preserve line numbers.
904 IN_MULTI_LINE_COMMENT
905 };
906
907 ParseState state = ParseState::BEGINING_OF_LINE;
908 size_t pos = 0;
909
910 while (pos < len)
911 {
912 char c = str[pos];
913 char next = pos + 1 < len ? str[pos + 1] : 0;
914
915 // Check for newlines
916 if (c == '\n' || c == '\r')
917 {
918 if (state != ParseState::IN_MULTI_LINE_COMMENT)
919 {
920 state = ParseState::BEGINING_OF_LINE;
921 }
922
923 pos++;
924 continue;
925 }
926
927 switch (state)
928 {
929 case ParseState::BEGINING_OF_LINE:
930 if (c == ' ')
931 {
932 // Maintain the BEGINING_OF_LINE state until a non-space is seen
933 pos++;
934 }
935 else if (c == '#')
936 {
937 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
938 pos++;
939 }
940 else
941 {
942 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
943 state = ParseState::MIDDLE_OF_LINE;
944 }
945 break;
946
947 case ParseState::MIDDLE_OF_LINE:
948 if (c == '/' && next == '/')
949 {
950 state = ParseState::IN_SINGLE_LINE_COMMENT;
951 pos++;
952 }
953 else if (c == '/' && next == '*')
954 {
955 state = ParseState::IN_MULTI_LINE_COMMENT;
956 pos++;
957 }
958 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
959 {
960 // Skip line continuation characters
961 }
962 else if (!IsValidESSLCharacter(c))
963 {
964 return false;
965 }
966 pos++;
967 break;
968
969 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700970 // Line-continuation characters may not be permitted.
971 // Otherwise, just pass it through. Do not parse comments in this state.
972 if (!lineContinuationAllowed && c == '\\')
973 {
974 return false;
975 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400976 pos++;
977 break;
978
979 case ParseState::IN_SINGLE_LINE_COMMENT:
980 // Line-continuation characters are processed before comment processing.
981 // Advance string if a new line character is immediately behind
982 // line-continuation character.
983 if (c == '\\' && (next == '\n' || next == '\r'))
984 {
985 pos++;
986 }
987 pos++;
988 break;
989
990 case ParseState::IN_MULTI_LINE_COMMENT:
991 if (c == '*' && next == '/')
992 {
993 state = ParseState::MIDDLE_OF_LINE;
994 pos++;
995 }
996 pos++;
997 break;
998 }
999 }
1000
1001 return true;
1002}
1003
Jamie Madill5b772312018-03-08 20:28:32 -05001004bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001005{
1006 ASSERT(context->isWebGL());
1007
1008 // WebGL 1.0 [Section 6.16] GLSL Constructs
1009 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1010 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1011 {
Jamie Madille0472f32018-11-27 16:32:45 -05001012 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001013 return false;
1014 }
1015
1016 return true;
1017}
1018
Jamie Madill5b772312018-03-08 20:28:32 -05001019bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001020{
1021 ASSERT(context->isWebGL());
1022
1023 if (context->isWebGL1() && length > 256)
1024 {
1025 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1026 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1027 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001028 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001029
1030 return false;
1031 }
1032 else if (length > 1024)
1033 {
1034 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1035 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001036 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001037 return false;
1038 }
1039
1040 return true;
1041}
1042
Jamie Madill007530e2017-12-28 14:27:04 -05001043bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1044{
1045 if (!context->getExtensions().pathRendering)
1046 {
Jamie Madill610640f2018-11-21 17:28:41 -05001047 context->validationError(GL_INVALID_OPERATION,
1048 "GL_CHROMIUM_path_rendering is not available.");
Jamie Madill007530e2017-12-28 14:27:04 -05001049 return false;
1050 }
1051
1052 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1053 {
Jamie Madille0472f32018-11-27 16:32:45 -05001054 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001055 return false;
1056 }
1057 return true;
1058}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001059
1060bool ValidBlendFunc(const Context *context, GLenum val)
1061{
1062 const gl::Extensions &ext = context->getExtensions();
1063
1064 // these are always valid for src and dst.
1065 switch (val)
1066 {
1067 case GL_ZERO:
1068 case GL_ONE:
1069 case GL_SRC_COLOR:
1070 case GL_ONE_MINUS_SRC_COLOR:
1071 case GL_DST_COLOR:
1072 case GL_ONE_MINUS_DST_COLOR:
1073 case GL_SRC_ALPHA:
1074 case GL_ONE_MINUS_SRC_ALPHA:
1075 case GL_DST_ALPHA:
1076 case GL_ONE_MINUS_DST_ALPHA:
1077 case GL_CONSTANT_COLOR:
1078 case GL_ONE_MINUS_CONSTANT_COLOR:
1079 case GL_CONSTANT_ALPHA:
1080 case GL_ONE_MINUS_CONSTANT_ALPHA:
1081 return true;
1082
1083 // EXT_blend_func_extended.
1084 case GL_SRC1_COLOR_EXT:
1085 case GL_SRC1_ALPHA_EXT:
1086 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1087 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1088 case GL_SRC_ALPHA_SATURATE_EXT:
1089 return ext.blendFuncExtended;
1090
1091 default:
1092 return false;
1093 }
1094}
1095
1096bool ValidSrcBlendFunc(const Context *context, GLenum val)
1097{
1098 if (ValidBlendFunc(context, val))
1099 return true;
1100
1101 if (val == GL_SRC_ALPHA_SATURATE)
1102 return true;
1103
1104 return false;
1105}
1106
1107bool ValidDstBlendFunc(const Context *context, GLenum val)
1108{
1109 if (ValidBlendFunc(context, val))
1110 return true;
1111
1112 if (val == GL_SRC_ALPHA_SATURATE)
1113 {
1114 if (context->getClientMajorVersion() >= 3)
1115 return true;
1116 }
1117
1118 return false;
1119}
1120
Jamie Madillac66f982018-10-09 18:30:01 -04001121void RecordBindTextureTypeError(Context *context, TextureType target)
1122{
1123 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1124
1125 switch (target)
1126 {
1127 case TextureType::Rectangle:
1128 ASSERT(!context->getExtensions().textureRectangle);
Jamie Madill610640f2018-11-21 17:28:41 -05001129 context->validationError(GL_INVALID_ENUM,
1130 "Context does not support GL_ANGLE_texture_rectangle");
Jamie Madillac66f982018-10-09 18:30:01 -04001131 break;
1132
1133 case TextureType::_3D:
1134 case TextureType::_2DArray:
1135 ASSERT(context->getClientMajorVersion() < 3);
Jamie Madille0472f32018-11-27 16:32:45 -05001136 context->validationError(GL_INVALID_ENUM, kES3Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001137 break;
1138
1139 case TextureType::_2DMultisample:
Yizhou Jiang7818a852018-09-06 15:02:04 +08001140 ASSERT(context->getClientVersion() < Version(3, 1) &&
1141 !context->getExtensions().textureMultisample);
Jamie Madille0472f32018-11-27 16:32:45 -05001142 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
Jamie Madillac66f982018-10-09 18:30:01 -04001143 break;
1144
1145 case TextureType::_2DMultisampleArray:
1146 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
Jamie Madillac66f982018-10-09 18:30:01 -04001148 break;
1149
1150 case TextureType::External:
1151 ASSERT(!context->getExtensions().eglImageExternal &&
1152 !context->getExtensions().eglStreamConsumerExternal);
Jamie Madill610640f2018-11-21 17:28:41 -05001153 context->validationError(GL_INVALID_ENUM, "External texture extension not enabled");
Jamie Madillac66f982018-10-09 18:30:01 -04001154 break;
1155
1156 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001157 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillac66f982018-10-09 18:30:01 -04001158 }
1159}
Jamie Madillc29968b2016-01-20 11:17:23 -05001160} // anonymous namespace
1161
Geoff Langff5b2d52016-09-07 11:32:23 -04001162bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001163 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001164 GLint level,
1165 GLenum internalformat,
1166 bool isCompressed,
1167 bool isSubImage,
1168 GLint xoffset,
1169 GLint yoffset,
1170 GLsizei width,
1171 GLsizei height,
1172 GLint border,
1173 GLenum format,
1174 GLenum type,
1175 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001176 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177{
Jamie Madill6f38f822014-06-06 17:12:20 -04001178 if (!ValidTexture2DDestinationTarget(context, target))
1179 {
Jamie Madille0472f32018-11-27 16:32:45 -05001180 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001181 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001182 }
1183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001184 TextureType texType = TextureTargetToType(target);
1185 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001186 {
Jamie Madill610640f2018-11-21 17:28:41 -05001187 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001188 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001189 }
1190
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001191 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001192 {
Jamie Madille0472f32018-11-27 16:32:45 -05001193 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001194 return false;
1195 }
1196
1197 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001198 std::numeric_limits<GLsizei>::max() - yoffset < height)
1199 {
Jamie Madille0472f32018-11-27 16:32:45 -05001200 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001201 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001202 }
1203
Geoff Lang6e898aa2017-06-02 11:17:26 -04001204 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1205 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1206 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1207 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1208 // case.
1209 bool nonEqualFormatsAllowed =
1210 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1211 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1212
1213 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001214 {
Jamie Madille0472f32018-11-27 16:32:45 -05001215 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langb1196682014-07-23 13:47:29 -04001216 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 }
1218
Geoff Langaae65a42014-05-26 12:43:44 -04001219 const gl::Caps &caps = context->getCaps();
1220
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001221 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001222 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001223 case TextureType::_2D:
1224 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1225 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1226 {
Jamie Madille0472f32018-11-27 16:32:45 -05001227 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001228 return false;
1229 }
1230 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001231
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001232 case TextureType::Rectangle:
1233 ASSERT(level == 0);
1234 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1235 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1236 {
Jamie Madille0472f32018-11-27 16:32:45 -05001237 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001238 return false;
1239 }
1240 if (isCompressed)
1241 {
Jamie Madill610640f2018-11-21 17:28:41 -05001242 context->validationError(GL_INVALID_ENUM,
1243 "Rectangle texture cannot have a compressed format.");
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001244 return false;
1245 }
1246 break;
1247
1248 case TextureType::CubeMap:
1249 if (!isSubImage && width != height)
1250 {
Jamie Madille0472f32018-11-27 16:32:45 -05001251 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001252 return false;
1253 }
1254
1255 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1256 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1257 {
Jamie Madille0472f32018-11-27 16:32:45 -05001258 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001259 return false;
1260 }
1261 break;
1262
1263 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001264 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001265 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001266 }
1267
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001268 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001269 if (!texture)
1270 {
Jamie Madille0472f32018-11-27 16:32:45 -05001271 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001272 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001273 }
1274
Geoff Langa9be0dc2014-12-17 12:34:40 -05001275 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001276 {
Geoff Langca271392017-04-05 12:30:00 -04001277 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1278 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001279 {
Jamie Madill610640f2018-11-21 17:28:41 -05001280 context->validationError(GL_INVALID_OPERATION, "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001281 return false;
1282 }
1283
Geoff Langa9be0dc2014-12-17 12:34:40 -05001284 if (format != GL_NONE)
1285 {
Geoff Langca271392017-04-05 12:30:00 -04001286 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1287 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001288 {
Jamie Madille0472f32018-11-27 16:32:45 -05001289 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001290 return false;
1291 }
1292 }
1293
1294 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1295 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1296 {
Jamie Madille0472f32018-11-27 16:32:45 -05001297 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001298 return false;
1299 }
Geoff Langfb052642017-10-24 13:42:09 -04001300
1301 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001302 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001303 {
Jamie Madille0472f32018-11-27 16:32:45 -05001304 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
Geoff Langfb052642017-10-24 13:42:09 -04001305 return false;
1306 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001307 }
1308 else
1309 {
Geoff Lang69cce582015-09-17 13:20:36 -04001310 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001311 {
Jamie Madille0472f32018-11-27 16:32:45 -05001312 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001313 return false;
1314 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001315 }
1316
1317 // Verify zero border
1318 if (border != 0)
1319 {
Jamie Madille0472f32018-11-27 16:32:45 -05001320 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001321 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001322 }
1323
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001324 if (isCompressed)
1325 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001326 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001327 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1328 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001329
1330 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1331
1332 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001333 {
Jamie Madille0472f32018-11-27 16:32:45 -05001334 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001335 return false;
1336 }
1337
1338 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1339 context->getExtensions()))
1340 {
Jamie Madille0472f32018-11-27 16:32:45 -05001341 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001342 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001343 }
Geoff Lang966c9402017-04-18 12:38:27 -04001344
1345 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001346 {
Geoff Lange88e4542018-05-03 15:05:57 -04001347 // From the OES_compressed_ETC1_RGB8_texture spec:
1348 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1349 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1350 // ETC1_RGB8_OES.
1351 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1352 {
Jamie Madille0472f32018-11-27 16:32:45 -05001353 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001354 return false;
1355 }
1356
Geoff Lang966c9402017-04-18 12:38:27 -04001357 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1358 height, texture->getWidth(target, level),
1359 texture->getHeight(target, level)))
1360 {
Jamie Madill610640f2018-11-21 17:28:41 -05001361 context->validationError(GL_INVALID_OPERATION,
1362 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001363 return false;
1364 }
1365
1366 if (format != actualInternalFormat)
1367 {
Jamie Madille0472f32018-11-27 16:32:45 -05001368 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001369 return false;
1370 }
1371 }
1372 else
1373 {
1374 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1375 {
Jamie Madill610640f2018-11-21 17:28:41 -05001376 context->validationError(GL_INVALID_OPERATION,
1377 "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001378 return false;
1379 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001380 }
1381 }
1382 else
1383 {
1384 // validate <type> by itself (used as secondary key below)
1385 switch (type)
1386 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001387 case GL_UNSIGNED_BYTE:
1388 case GL_UNSIGNED_SHORT_5_6_5:
1389 case GL_UNSIGNED_SHORT_4_4_4_4:
1390 case GL_UNSIGNED_SHORT_5_5_5_1:
1391 case GL_UNSIGNED_SHORT:
1392 case GL_UNSIGNED_INT:
1393 case GL_UNSIGNED_INT_24_8_OES:
1394 case GL_HALF_FLOAT_OES:
1395 case GL_FLOAT:
1396 break;
1397 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001398 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001399 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001400 }
1401
1402 // validate <format> + <type> combinations
1403 // - invalid <format> -> sets INVALID_ENUM
1404 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1405 switch (format)
1406 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001407 case GL_ALPHA:
1408 case GL_LUMINANCE:
1409 case GL_LUMINANCE_ALPHA:
1410 switch (type)
1411 {
1412 case GL_UNSIGNED_BYTE:
1413 case GL_FLOAT:
1414 case GL_HALF_FLOAT_OES:
1415 break;
1416 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001417 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001418 return false;
1419 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001420 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001421 case GL_RED:
1422 case GL_RG:
1423 if (!context->getExtensions().textureRG)
1424 {
Jamie Madille0472f32018-11-27 16:32:45 -05001425 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 return false;
1427 }
1428 switch (type)
1429 {
1430 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001431 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001432 case GL_FLOAT:
1433 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001434 if (!context->getExtensions().textureFloat)
1435 {
Jamie Madille0472f32018-11-27 16:32:45 -05001436 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001437 return false;
1438 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001439 break;
1440 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001441 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001442 return false;
1443 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001444 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001445 case GL_RGB:
1446 switch (type)
1447 {
1448 case GL_UNSIGNED_BYTE:
1449 case GL_UNSIGNED_SHORT_5_6_5:
1450 case GL_FLOAT:
1451 case GL_HALF_FLOAT_OES:
1452 break;
1453 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001454 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001455 return false;
1456 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001457 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001458 case GL_RGBA:
1459 switch (type)
1460 {
1461 case GL_UNSIGNED_BYTE:
1462 case GL_UNSIGNED_SHORT_4_4_4_4:
1463 case GL_UNSIGNED_SHORT_5_5_5_1:
1464 case GL_FLOAT:
1465 case GL_HALF_FLOAT_OES:
1466 break;
1467 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001468 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001469 return false;
1470 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001471 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001472 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001473 if (!context->getExtensions().textureFormatBGRA8888)
1474 {
Jamie Madille0472f32018-11-27 16:32:45 -05001475 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001476 return false;
1477 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001478 switch (type)
1479 {
1480 case GL_UNSIGNED_BYTE:
1481 break;
1482 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001483 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001484 return false;
1485 }
1486 break;
1487 case GL_SRGB_EXT:
1488 case GL_SRGB_ALPHA_EXT:
1489 if (!context->getExtensions().sRGB)
1490 {
Jamie Madille0472f32018-11-27 16:32:45 -05001491 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001492 return false;
1493 }
1494 switch (type)
1495 {
1496 case GL_UNSIGNED_BYTE:
1497 break;
1498 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001499 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 return false;
1501 }
1502 break;
1503 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1504 // handled below
1505 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1506 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1507 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1508 break;
1509 case GL_DEPTH_COMPONENT:
1510 switch (type)
1511 {
1512 case GL_UNSIGNED_SHORT:
1513 case GL_UNSIGNED_INT:
1514 break;
1515 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001516 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001517 return false;
1518 }
1519 break;
1520 case GL_DEPTH_STENCIL_OES:
1521 switch (type)
1522 {
1523 case GL_UNSIGNED_INT_24_8_OES:
1524 break;
1525 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001526 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001527 return false;
1528 }
1529 break;
1530 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001531 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001532 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001533 }
1534
1535 switch (format)
1536 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001537 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1538 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1539 if (context->getExtensions().textureCompressionDXT1)
1540 {
Jamie Madille0472f32018-11-27 16:32:45 -05001541 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001542 return false;
1543 }
1544 else
1545 {
Jamie Madille0472f32018-11-27 16:32:45 -05001546 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001547 return false;
1548 }
1549 break;
1550 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1551 if (context->getExtensions().textureCompressionDXT3)
1552 {
Jamie Madille0472f32018-11-27 16:32:45 -05001553 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001554 return false;
1555 }
1556 else
1557 {
Jamie Madille0472f32018-11-27 16:32:45 -05001558 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001559 return false;
1560 }
1561 break;
1562 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1563 if (context->getExtensions().textureCompressionDXT5)
1564 {
Jamie Madille0472f32018-11-27 16:32:45 -05001565 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001566 return false;
1567 }
1568 else
1569 {
Jamie Madille0472f32018-11-27 16:32:45 -05001570 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001571 return false;
1572 }
1573 break;
1574 case GL_ETC1_RGB8_OES:
1575 if (context->getExtensions().compressedETC1RGB8Texture)
1576 {
Jamie Madille0472f32018-11-27 16:32:45 -05001577 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001578 return false;
1579 }
1580 else
1581 {
Jamie Madille0472f32018-11-27 16:32:45 -05001582 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001583 return false;
1584 }
1585 break;
1586 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001587 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1588 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1589 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1590 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001591 if (context->getExtensions().lossyETCDecode)
1592 {
Jamie Madill610640f2018-11-21 17:28:41 -05001593 context->validationError(GL_INVALID_OPERATION,
1594 "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001595 return false;
1596 }
1597 else
1598 {
Jamie Madill610640f2018-11-21 17:28:41 -05001599 context->validationError(GL_INVALID_ENUM,
1600 "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001601 return false;
1602 }
1603 break;
1604 case GL_DEPTH_COMPONENT:
1605 case GL_DEPTH_STENCIL_OES:
1606 if (!context->getExtensions().depthTextures)
1607 {
Jamie Madille0472f32018-11-27 16:32:45 -05001608 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001609 return false;
1610 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001611 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001612 {
Jamie Madille0472f32018-11-27 16:32:45 -05001613 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001614 return false;
1615 }
1616 // OES_depth_texture supports loading depth data and multiple levels,
1617 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001618 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001619 {
Jamie Madille0472f32018-11-27 16:32:45 -05001620 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
Brandon Jonesafa75152017-07-21 13:11:29 -07001621 return false;
1622 }
1623 if (level != 0)
1624 {
Jamie Madille0472f32018-11-27 16:32:45 -05001625 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001626 return false;
1627 }
1628 break;
1629 default:
1630 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001631 }
1632
Geoff Lang6e898aa2017-06-02 11:17:26 -04001633 if (!isSubImage)
1634 {
1635 switch (internalformat)
1636 {
1637 case GL_RGBA32F:
1638 if (!context->getExtensions().colorBufferFloatRGBA)
1639 {
Jamie Madill610640f2018-11-21 17:28:41 -05001640 context->validationError(GL_INVALID_ENUM,
1641 "Sized GL_RGBA32F internal format requires "
1642 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001643 return false;
1644 }
1645 if (type != GL_FLOAT)
1646 {
Jamie Madille0472f32018-11-27 16:32:45 -05001647 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001648 return false;
1649 }
1650 if (format != GL_RGBA)
1651 {
Jamie Madille0472f32018-11-27 16:32:45 -05001652 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001653 return false;
1654 }
1655 break;
1656
1657 case GL_RGB32F:
1658 if (!context->getExtensions().colorBufferFloatRGB)
1659 {
Jamie Madill610640f2018-11-21 17:28:41 -05001660 context->validationError(GL_INVALID_ENUM,
1661 "Sized GL_RGB32F internal format requires "
1662 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001663 return false;
1664 }
1665 if (type != GL_FLOAT)
1666 {
Jamie Madille0472f32018-11-27 16:32:45 -05001667 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001668 return false;
1669 }
1670 if (format != GL_RGB)
1671 {
Jamie Madille0472f32018-11-27 16:32:45 -05001672 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001673 return false;
1674 }
1675 break;
1676
1677 default:
1678 break;
1679 }
1680 }
1681
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 if (type == GL_FLOAT)
1683 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001684 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001685 {
Jamie Madille0472f32018-11-27 16:32:45 -05001686 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001687 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001688 }
1689 }
1690 else if (type == GL_HALF_FLOAT_OES)
1691 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001692 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001693 {
Jamie Madille0472f32018-11-27 16:32:45 -05001694 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001695 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001696 }
1697 }
1698 }
1699
Geoff Langdbcced82017-06-06 15:55:54 -04001700 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001701 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001702 imageSize))
1703 {
1704 return false;
1705 }
1706
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001707 return true;
1708}
1709
He Yunchaoced53ae2016-11-29 15:00:51 +08001710bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001711 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001712 GLsizei levels,
1713 GLenum internalformat,
1714 GLsizei width,
1715 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001716{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001717 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1718 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001719 {
Jamie Madille0472f32018-11-27 16:32:45 -05001720 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001721 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001722 }
1723
1724 if (width < 1 || height < 1 || levels < 1)
1725 {
Jamie Madille0472f32018-11-27 16:32:45 -05001726 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001727 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728 }
1729
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001730 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001731 {
Jamie Madille0472f32018-11-27 16:32:45 -05001732 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001733 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001734 }
1735
1736 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1737 {
Jamie Madille0472f32018-11-27 16:32:45 -05001738 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001739 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001740 }
1741
Geoff Langca271392017-04-05 12:30:00 -04001742 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001743 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001744 {
Jamie Madille0472f32018-11-27 16:32:45 -05001745 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001746 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001747 }
1748
Geoff Langaae65a42014-05-26 12:43:44 -04001749 const gl::Caps &caps = context->getCaps();
1750
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001751 switch (target)
1752 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001753 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001754 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1755 static_cast<GLuint>(height) > caps.max2DTextureSize)
1756 {
Jamie Madille0472f32018-11-27 16:32:45 -05001757 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001758 return false;
1759 }
1760 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001761 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001762 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001763 {
Jamie Madille0472f32018-11-27 16:32:45 -05001764 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001765 return false;
1766 }
1767
1768 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1769 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1770 {
Jamie Madille0472f32018-11-27 16:32:45 -05001771 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001772 return false;
1773 }
1774 if (formatInfo.compressed)
1775 {
Jamie Madille0472f32018-11-27 16:32:45 -05001776 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001777 return false;
1778 }
1779 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001780 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001781 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1782 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1783 {
Jamie Madille0472f32018-11-27 16:32:45 -05001784 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001785 return false;
1786 }
1787 break;
1788 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001789 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001790 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001791 }
1792
Geoff Langc0b9ef42014-07-02 10:02:37 -04001793 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 {
1795 if (!gl::isPow2(width) || !gl::isPow2(height))
1796 {
Jamie Madille0472f32018-11-27 16:32:45 -05001797 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001798 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001799 }
1800 }
1801
1802 switch (internalformat)
1803 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001804 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1805 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1806 if (!context->getExtensions().textureCompressionDXT1)
1807 {
Jamie Madille0472f32018-11-27 16:32:45 -05001808 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001809 return false;
1810 }
1811 break;
1812 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1813 if (!context->getExtensions().textureCompressionDXT3)
1814 {
Jamie Madille0472f32018-11-27 16:32:45 -05001815 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001816 return false;
1817 }
1818 break;
1819 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1820 if (!context->getExtensions().textureCompressionDXT5)
1821 {
Jamie Madille0472f32018-11-27 16:32:45 -05001822 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001823 return false;
1824 }
1825 break;
1826 case GL_ETC1_RGB8_OES:
1827 if (!context->getExtensions().compressedETC1RGB8Texture)
1828 {
Jamie Madille0472f32018-11-27 16:32:45 -05001829 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001830 return false;
1831 }
1832 break;
1833 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001834 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1835 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1836 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1837 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001838 if (!context->getExtensions().lossyETCDecode)
1839 {
Jamie Madill610640f2018-11-21 17:28:41 -05001840 context->validationError(GL_INVALID_ENUM,
1841 "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001842 return false;
1843 }
1844 break;
1845 case GL_RGBA32F_EXT:
1846 case GL_RGB32F_EXT:
1847 case GL_ALPHA32F_EXT:
1848 case GL_LUMINANCE32F_EXT:
1849 case GL_LUMINANCE_ALPHA32F_EXT:
1850 if (!context->getExtensions().textureFloat)
1851 {
Jamie Madille0472f32018-11-27 16:32:45 -05001852 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001853 return false;
1854 }
1855 break;
1856 case GL_RGBA16F_EXT:
1857 case GL_RGB16F_EXT:
1858 case GL_ALPHA16F_EXT:
1859 case GL_LUMINANCE16F_EXT:
1860 case GL_LUMINANCE_ALPHA16F_EXT:
1861 if (!context->getExtensions().textureHalfFloat)
1862 {
Jamie Madille0472f32018-11-27 16:32:45 -05001863 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001864 return false;
1865 }
1866 break;
1867 case GL_R8_EXT:
1868 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001869 if (!context->getExtensions().textureRG)
1870 {
Jamie Madille0472f32018-11-27 16:32:45 -05001871 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001872 return false;
1873 }
1874 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001875 case GL_R16F_EXT:
1876 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001877 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1878 {
Jamie Madille0472f32018-11-27 16:32:45 -05001879 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001880 return false;
1881 }
1882 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001883 case GL_R32F_EXT:
1884 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001885 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001886 {
Jamie Madille0472f32018-11-27 16:32:45 -05001887 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001888 return false;
1889 }
1890 break;
1891 case GL_DEPTH_COMPONENT16:
1892 case GL_DEPTH_COMPONENT32_OES:
1893 case GL_DEPTH24_STENCIL8_OES:
1894 if (!context->getExtensions().depthTextures)
1895 {
Jamie Madille0472f32018-11-27 16:32:45 -05001896 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001897 return false;
1898 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001899 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001900 {
Jamie Madille0472f32018-11-27 16:32:45 -05001901 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001902 return false;
1903 }
1904 // ANGLE_depth_texture only supports 1-level textures
1905 if (levels != 1)
1906 {
Jamie Madille0472f32018-11-27 16:32:45 -05001907 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
He Yunchaoced53ae2016-11-29 15:00:51 +08001908 return false;
1909 }
1910 break;
1911 default:
1912 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001913 }
1914
Geoff Lang691e58c2014-12-19 17:03:25 -05001915 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001916 if (!texture || texture->id() == 0)
1917 {
Jamie Madille0472f32018-11-27 16:32:45 -05001918 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001919 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001920 }
1921
Geoff Lang69cce582015-09-17 13:20:36 -04001922 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001923 {
Jamie Madille0472f32018-11-27 16:32:45 -05001924 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001925 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001926 }
1927
1928 return true;
1929}
1930
He Yunchaoced53ae2016-11-29 15:00:51 +08001931bool ValidateDiscardFramebufferEXT(Context *context,
1932 GLenum target,
1933 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001934 const GLenum *attachments)
1935{
Jamie Madillc29968b2016-01-20 11:17:23 -05001936 if (!context->getExtensions().discardFramebuffer)
1937 {
Jamie Madille0472f32018-11-27 16:32:45 -05001938 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001939 return false;
1940 }
1941
Austin Kinross08332632015-05-05 13:35:47 -07001942 bool defaultFramebuffer = false;
1943
1944 switch (target)
1945 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001946 case GL_FRAMEBUFFER:
1947 defaultFramebuffer =
1948 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1949 break;
1950 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001951 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001952 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001953 }
1954
He Yunchaoced53ae2016-11-29 15:00:51 +08001955 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1956 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001957}
1958
Austin Kinrossbc781f32015-10-26 09:27:38 -07001959bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1960{
1961 if (!context->getExtensions().vertexArrayObject)
1962 {
Jamie Madille0472f32018-11-27 16:32:45 -05001963 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001964 return false;
1965 }
1966
1967 return ValidateBindVertexArrayBase(context, array);
1968}
1969
Jamie Madilld7576732017-08-26 18:49:50 -04001970bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001971{
1972 if (!context->getExtensions().vertexArrayObject)
1973 {
Jamie Madille0472f32018-11-27 16:32:45 -05001974 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001975 return false;
1976 }
1977
Olli Etuaho41997e72016-03-10 13:38:39 +02001978 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001979}
1980
Jamie Madilld7576732017-08-26 18:49:50 -04001981bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001982{
1983 if (!context->getExtensions().vertexArrayObject)
1984 {
Jamie Madille0472f32018-11-27 16:32:45 -05001985 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001986 return false;
1987 }
1988
Olli Etuaho41997e72016-03-10 13:38:39 +02001989 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001990}
1991
Jamie Madilld7576732017-08-26 18:49:50 -04001992bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001993{
1994 if (!context->getExtensions().vertexArrayObject)
1995 {
Jamie Madille0472f32018-11-27 16:32:45 -05001996 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001997 return false;
1998 }
1999
2000 return true;
2001}
Geoff Langc5629752015-12-07 16:29:04 -05002002
2003bool ValidateProgramBinaryOES(Context *context,
2004 GLuint program,
2005 GLenum binaryFormat,
2006 const void *binary,
2007 GLint length)
2008{
2009 if (!context->getExtensions().getProgramBinary)
2010 {
Jamie Madille0472f32018-11-27 16:32:45 -05002011 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002012 return false;
2013 }
2014
2015 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2016}
2017
2018bool ValidateGetProgramBinaryOES(Context *context,
2019 GLuint program,
2020 GLsizei bufSize,
2021 GLsizei *length,
2022 GLenum *binaryFormat,
2023 void *binary)
2024{
2025 if (!context->getExtensions().getProgramBinary)
2026 {
Jamie Madille0472f32018-11-27 16:32:45 -05002027 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002028 return false;
2029 }
2030
2031 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2032}
Geoff Lange102fee2015-12-10 11:23:30 -05002033
Geoff Lang70d0f492015-12-10 17:45:46 -05002034static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2035{
2036 switch (source)
2037 {
2038 case GL_DEBUG_SOURCE_API:
2039 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2040 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2041 case GL_DEBUG_SOURCE_OTHER:
2042 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2043 return !mustBeThirdPartyOrApplication;
2044
2045 case GL_DEBUG_SOURCE_THIRD_PARTY:
2046 case GL_DEBUG_SOURCE_APPLICATION:
2047 return true;
2048
2049 default:
2050 return false;
2051 }
2052}
2053
2054static bool ValidDebugType(GLenum type)
2055{
2056 switch (type)
2057 {
2058 case GL_DEBUG_TYPE_ERROR:
2059 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2060 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2061 case GL_DEBUG_TYPE_PERFORMANCE:
2062 case GL_DEBUG_TYPE_PORTABILITY:
2063 case GL_DEBUG_TYPE_OTHER:
2064 case GL_DEBUG_TYPE_MARKER:
2065 case GL_DEBUG_TYPE_PUSH_GROUP:
2066 case GL_DEBUG_TYPE_POP_GROUP:
2067 return true;
2068
2069 default:
2070 return false;
2071 }
2072}
2073
2074static bool ValidDebugSeverity(GLenum severity)
2075{
2076 switch (severity)
2077 {
2078 case GL_DEBUG_SEVERITY_HIGH:
2079 case GL_DEBUG_SEVERITY_MEDIUM:
2080 case GL_DEBUG_SEVERITY_LOW:
2081 case GL_DEBUG_SEVERITY_NOTIFICATION:
2082 return true;
2083
2084 default:
2085 return false;
2086 }
2087}
2088
Geoff Lange102fee2015-12-10 11:23:30 -05002089bool ValidateDebugMessageControlKHR(Context *context,
2090 GLenum source,
2091 GLenum type,
2092 GLenum severity,
2093 GLsizei count,
2094 const GLuint *ids,
2095 GLboolean enabled)
2096{
2097 if (!context->getExtensions().debug)
2098 {
Jamie Madille0472f32018-11-27 16:32:45 -05002099 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002100 return false;
2101 }
2102
Geoff Lang70d0f492015-12-10 17:45:46 -05002103 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2104 {
Jamie Madille0472f32018-11-27 16:32:45 -05002105 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002106 return false;
2107 }
2108
2109 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2110 {
Jamie Madille0472f32018-11-27 16:32:45 -05002111 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002112 return false;
2113 }
2114
2115 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2116 {
Jamie Madille0472f32018-11-27 16:32:45 -05002117 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 if (count > 0)
2122 {
2123 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2124 {
Jamie Madill610640f2018-11-21 17:28:41 -05002125 context->validationError(
2126 GL_INVALID_OPERATION,
2127 "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002128 return false;
2129 }
2130
2131 if (severity != GL_DONT_CARE)
2132 {
Jamie Madill610640f2018-11-21 17:28:41 -05002133 context->validationError(
2134 GL_INVALID_OPERATION,
2135 "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002136 return false;
2137 }
2138 }
2139
Geoff Lange102fee2015-12-10 11:23:30 -05002140 return true;
2141}
2142
2143bool ValidateDebugMessageInsertKHR(Context *context,
2144 GLenum source,
2145 GLenum type,
2146 GLuint id,
2147 GLenum severity,
2148 GLsizei length,
2149 const GLchar *buf)
2150{
2151 if (!context->getExtensions().debug)
2152 {
Jamie Madille0472f32018-11-27 16:32:45 -05002153 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002154 return false;
2155 }
2156
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002157 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 {
2159 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2160 // not generate an error.
2161 return false;
2162 }
2163
2164 if (!ValidDebugSeverity(severity))
2165 {
Jamie Madille0472f32018-11-27 16:32:45 -05002166 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002167 return false;
2168 }
2169
2170 if (!ValidDebugType(type))
2171 {
Jamie Madille0472f32018-11-27 16:32:45 -05002172 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002173 return false;
2174 }
2175
2176 if (!ValidDebugSource(source, true))
2177 {
Jamie Madille0472f32018-11-27 16:32:45 -05002178 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002179 return false;
2180 }
2181
2182 size_t messageLength = (length < 0) ? strlen(buf) : length;
2183 if (messageLength > context->getExtensions().maxDebugMessageLength)
2184 {
Jamie Madill610640f2018-11-21 17:28:41 -05002185 context->validationError(GL_INVALID_VALUE,
2186 "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002187 return false;
2188 }
2189
Geoff Lange102fee2015-12-10 11:23:30 -05002190 return true;
2191}
2192
2193bool ValidateDebugMessageCallbackKHR(Context *context,
2194 GLDEBUGPROCKHR callback,
2195 const void *userParam)
2196{
2197 if (!context->getExtensions().debug)
2198 {
Jamie Madille0472f32018-11-27 16:32:45 -05002199 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002200 return false;
2201 }
2202
Geoff Lange102fee2015-12-10 11:23:30 -05002203 return true;
2204}
2205
2206bool ValidateGetDebugMessageLogKHR(Context *context,
2207 GLuint count,
2208 GLsizei bufSize,
2209 GLenum *sources,
2210 GLenum *types,
2211 GLuint *ids,
2212 GLenum *severities,
2213 GLsizei *lengths,
2214 GLchar *messageLog)
2215{
2216 if (!context->getExtensions().debug)
2217 {
Jamie Madille0472f32018-11-27 16:32:45 -05002218 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002219 return false;
2220 }
2221
Geoff Lang70d0f492015-12-10 17:45:46 -05002222 if (bufSize < 0 && messageLog != nullptr)
2223 {
Jamie Madille0472f32018-11-27 16:32:45 -05002224 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002225 return false;
2226 }
2227
Geoff Lange102fee2015-12-10 11:23:30 -05002228 return true;
2229}
2230
2231bool ValidatePushDebugGroupKHR(Context *context,
2232 GLenum source,
2233 GLuint id,
2234 GLsizei length,
2235 const GLchar *message)
2236{
2237 if (!context->getExtensions().debug)
2238 {
Jamie Madille0472f32018-11-27 16:32:45 -05002239 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002240 return false;
2241 }
2242
Geoff Lang70d0f492015-12-10 17:45:46 -05002243 if (!ValidDebugSource(source, true))
2244 {
Jamie Madille0472f32018-11-27 16:32:45 -05002245 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002246 return false;
2247 }
2248
2249 size_t messageLength = (length < 0) ? strlen(message) : length;
2250 if (messageLength > context->getExtensions().maxDebugMessageLength)
2251 {
Jamie Madill610640f2018-11-21 17:28:41 -05002252 context->validationError(GL_INVALID_VALUE,
2253 "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002254 return false;
2255 }
2256
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002257 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2259 {
Jamie Madill610640f2018-11-21 17:28:41 -05002260 context->validationError(
2261 GL_STACK_OVERFLOW,
2262 "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002263 return false;
2264 }
2265
Geoff Lange102fee2015-12-10 11:23:30 -05002266 return true;
2267}
2268
2269bool ValidatePopDebugGroupKHR(Context *context)
2270{
2271 if (!context->getExtensions().debug)
2272 {
Jamie Madille0472f32018-11-27 16:32:45 -05002273 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002274 return false;
2275 }
2276
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002277 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002278 if (currentStackSize <= 1)
2279 {
Jamie Madill610640f2018-11-21 17:28:41 -05002280 context->validationError(GL_STACK_UNDERFLOW, "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002281 return false;
2282 }
2283
2284 return true;
2285}
2286
2287static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2288{
2289 switch (identifier)
2290 {
2291 case GL_BUFFER:
2292 if (context->getBuffer(name) == nullptr)
2293 {
Jamie Madill610640f2018-11-21 17:28:41 -05002294 context->validationError(GL_INVALID_VALUE, "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 return false;
2296 }
2297 return true;
2298
2299 case GL_SHADER:
2300 if (context->getShader(name) == nullptr)
2301 {
Jamie Madill610640f2018-11-21 17:28:41 -05002302 context->validationError(GL_INVALID_VALUE, "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002303 return false;
2304 }
2305 return true;
2306
2307 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002308 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002309 {
Jamie Madill610640f2018-11-21 17:28:41 -05002310 context->validationError(GL_INVALID_VALUE, "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002311 return false;
2312 }
2313 return true;
2314
2315 case GL_VERTEX_ARRAY:
2316 if (context->getVertexArray(name) == nullptr)
2317 {
Jamie Madill610640f2018-11-21 17:28:41 -05002318 context->validationError(GL_INVALID_VALUE, "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002319 return false;
2320 }
2321 return true;
2322
2323 case GL_QUERY:
2324 if (context->getQuery(name) == nullptr)
2325 {
Jamie Madill610640f2018-11-21 17:28:41 -05002326 context->validationError(GL_INVALID_VALUE, "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002327 return false;
2328 }
2329 return true;
2330
2331 case GL_TRANSFORM_FEEDBACK:
2332 if (context->getTransformFeedback(name) == nullptr)
2333 {
Jamie Madill610640f2018-11-21 17:28:41 -05002334 context->validationError(GL_INVALID_VALUE,
2335 "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002336 return false;
2337 }
2338 return true;
2339
2340 case GL_SAMPLER:
2341 if (context->getSampler(name) == nullptr)
2342 {
Jamie Madill610640f2018-11-21 17:28:41 -05002343 context->validationError(GL_INVALID_VALUE, "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002344 return false;
2345 }
2346 return true;
2347
2348 case GL_TEXTURE:
2349 if (context->getTexture(name) == nullptr)
2350 {
Jamie Madill610640f2018-11-21 17:28:41 -05002351 context->validationError(GL_INVALID_VALUE, "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002352 return false;
2353 }
2354 return true;
2355
2356 case GL_RENDERBUFFER:
2357 if (context->getRenderbuffer(name) == nullptr)
2358 {
Jamie Madill610640f2018-11-21 17:28:41 -05002359 context->validationError(GL_INVALID_VALUE, "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 return false;
2361 }
2362 return true;
2363
2364 case GL_FRAMEBUFFER:
2365 if (context->getFramebuffer(name) == nullptr)
2366 {
Jamie Madill610640f2018-11-21 17:28:41 -05002367 context->validationError(GL_INVALID_VALUE, "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002368 return false;
2369 }
2370 return true;
2371
2372 default:
Jamie Madill610640f2018-11-21 17:28:41 -05002373 context->validationError(GL_INVALID_ENUM, "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002374 return false;
2375 }
Geoff Lange102fee2015-12-10 11:23:30 -05002376}
2377
Martin Radev9d901792016-07-15 15:58:58 +03002378static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2379{
2380 size_t labelLength = 0;
2381
2382 if (length < 0)
2383 {
2384 if (label != nullptr)
2385 {
2386 labelLength = strlen(label);
2387 }
2388 }
2389 else
2390 {
2391 labelLength = static_cast<size_t>(length);
2392 }
2393
2394 if (labelLength > context->getExtensions().maxLabelLength)
2395 {
Jamie Madill610640f2018-11-21 17:28:41 -05002396 context->validationError(GL_INVALID_VALUE,
2397 "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002398 return false;
2399 }
2400
2401 return true;
2402}
2403
Geoff Lange102fee2015-12-10 11:23:30 -05002404bool ValidateObjectLabelKHR(Context *context,
2405 GLenum identifier,
2406 GLuint name,
2407 GLsizei length,
2408 const GLchar *label)
2409{
2410 if (!context->getExtensions().debug)
2411 {
Jamie Madille0472f32018-11-27 16:32:45 -05002412 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002413 return false;
2414 }
2415
Geoff Lang70d0f492015-12-10 17:45:46 -05002416 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2417 {
2418 return false;
2419 }
2420
Martin Radev9d901792016-07-15 15:58:58 +03002421 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002422 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002423 return false;
2424 }
2425
Geoff Lange102fee2015-12-10 11:23:30 -05002426 return true;
2427}
2428
2429bool ValidateGetObjectLabelKHR(Context *context,
2430 GLenum identifier,
2431 GLuint name,
2432 GLsizei bufSize,
2433 GLsizei *length,
2434 GLchar *label)
2435{
2436 if (!context->getExtensions().debug)
2437 {
Jamie Madille0472f32018-11-27 16:32:45 -05002438 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002439 return false;
2440 }
2441
Geoff Lang70d0f492015-12-10 17:45:46 -05002442 if (bufSize < 0)
2443 {
Jamie Madille0472f32018-11-27 16:32:45 -05002444 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002445 return false;
2446 }
2447
2448 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2449 {
2450 return false;
2451 }
2452
Martin Radev9d901792016-07-15 15:58:58 +03002453 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002454}
2455
2456static bool ValidateObjectPtrName(Context *context, const void *ptr)
2457{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002458 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002459 {
Jamie Madill610640f2018-11-21 17:28:41 -05002460 context->validationError(GL_INVALID_VALUE, "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002461 return false;
2462 }
2463
Geoff Lange102fee2015-12-10 11:23:30 -05002464 return true;
2465}
2466
2467bool ValidateObjectPtrLabelKHR(Context *context,
2468 const void *ptr,
2469 GLsizei length,
2470 const GLchar *label)
2471{
2472 if (!context->getExtensions().debug)
2473 {
Jamie Madille0472f32018-11-27 16:32:45 -05002474 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002475 return false;
2476 }
2477
Geoff Lang70d0f492015-12-10 17:45:46 -05002478 if (!ValidateObjectPtrName(context, ptr))
2479 {
2480 return false;
2481 }
2482
Martin Radev9d901792016-07-15 15:58:58 +03002483 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002484 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002485 return false;
2486 }
2487
Geoff Lange102fee2015-12-10 11:23:30 -05002488 return true;
2489}
2490
2491bool ValidateGetObjectPtrLabelKHR(Context *context,
2492 const void *ptr,
2493 GLsizei bufSize,
2494 GLsizei *length,
2495 GLchar *label)
2496{
2497 if (!context->getExtensions().debug)
2498 {
Jamie Madille0472f32018-11-27 16:32:45 -05002499 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002500 return false;
2501 }
2502
Geoff Lang70d0f492015-12-10 17:45:46 -05002503 if (bufSize < 0)
2504 {
Jamie Madille0472f32018-11-27 16:32:45 -05002505 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002506 return false;
2507 }
2508
2509 if (!ValidateObjectPtrName(context, ptr))
2510 {
2511 return false;
2512 }
2513
Martin Radev9d901792016-07-15 15:58:58 +03002514 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002515}
2516
2517bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2518{
2519 if (!context->getExtensions().debug)
2520 {
Jamie Madille0472f32018-11-27 16:32:45 -05002521 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002522 return false;
2523 }
2524
Geoff Lang70d0f492015-12-10 17:45:46 -05002525 // TODO: represent this in Context::getQueryParameterInfo.
2526 switch (pname)
2527 {
2528 case GL_DEBUG_CALLBACK_FUNCTION:
2529 case GL_DEBUG_CALLBACK_USER_PARAM:
2530 break;
2531
2532 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002533 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002534 return false;
2535 }
2536
Geoff Lange102fee2015-12-10 11:23:30 -05002537 return true;
2538}
Jamie Madillc29968b2016-01-20 11:17:23 -05002539
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002540bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2541 GLenum pname,
2542 GLsizei bufSize,
2543 GLsizei *length,
2544 void **params)
2545{
2546 UNIMPLEMENTED();
2547 return false;
2548}
2549
Jamie Madillc29968b2016-01-20 11:17:23 -05002550bool ValidateBlitFramebufferANGLE(Context *context,
2551 GLint srcX0,
2552 GLint srcY0,
2553 GLint srcX1,
2554 GLint srcY1,
2555 GLint dstX0,
2556 GLint dstY0,
2557 GLint dstX1,
2558 GLint dstY1,
2559 GLbitfield mask,
2560 GLenum filter)
2561{
2562 if (!context->getExtensions().framebufferBlit)
2563 {
Jamie Madille0472f32018-11-27 16:32:45 -05002564 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002565 return false;
2566 }
2567
2568 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2569 {
2570 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002571 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002572 return false;
2573 }
2574
2575 if (filter == GL_LINEAR)
2576 {
Jamie Madille0472f32018-11-27 16:32:45 -05002577 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002578 return false;
2579 }
2580
Jamie Madill51f40ec2016-06-15 14:06:00 -04002581 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2582 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002583
2584 if (mask & GL_COLOR_BUFFER_BIT)
2585 {
2586 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2587 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2588
2589 if (readColorAttachment && drawColorAttachment)
2590 {
2591 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002592 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002593 readColorAttachment->type() != GL_RENDERBUFFER &&
2594 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2595 {
Jamie Madill610640f2018-11-21 17:28:41 -05002596 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002597 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002598 return false;
2599 }
2600
Geoff Langa15472a2015-08-11 11:48:03 -04002601 for (size_t drawbufferIdx = 0;
2602 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002603 {
Geoff Langa15472a2015-08-11 11:48:03 -04002604 const FramebufferAttachment *attachment =
2605 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2606 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002608 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002609 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002610 attachment->type() != GL_RENDERBUFFER &&
2611 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2612 {
Jamie Madill610640f2018-11-21 17:28:41 -05002613 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002614 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002615 return false;
2616 }
2617
2618 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002619 if (!Format::EquivalentForBlit(attachment->getFormat(),
2620 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002621 {
Jamie Madill610640f2018-11-21 17:28:41 -05002622 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002623 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002624 return false;
2625 }
2626 }
2627 }
2628
Jamie Madill427064d2018-04-13 16:20:34 -04002629 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002630 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002631 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2632 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2633 {
Jamie Madill610640f2018-11-21 17:28:41 -05002634 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002635 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002636 return false;
2637 }
2638 }
2639 }
2640
2641 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2642 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2643 for (size_t i = 0; i < 2; i++)
2644 {
2645 if (mask & masks[i])
2646 {
2647 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002648 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002649 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002650 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002651
2652 if (readBuffer && drawBuffer)
2653 {
2654 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2655 dstX0, dstY0, dstX1, dstY1))
2656 {
2657 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002658 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002659 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002660 return false;
2661 }
2662
2663 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2664 {
Jamie Madill610640f2018-11-21 17:28:41 -05002665 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002666 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002667 return false;
2668 }
2669 }
2670 }
2671 }
2672
2673 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2674 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002675}
Jamie Madillc29968b2016-01-20 11:17:23 -05002676
Jamie Madill5b772312018-03-08 20:28:32 -05002677bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002678{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002679 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002680 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002681
Jamie Madill427064d2018-04-13 16:20:34 -04002682 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002683 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 return false;
2685 }
2686
2687 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2688 {
Jamie Madille0472f32018-11-27 16:32:45 -05002689 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002690 return false;
2691 }
2692
Olli Etuaho94c91a92018-07-19 15:10:24 +03002693 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002694 {
2695 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2696 GL_SIGNED_NORMALIZED};
2697
Corentin Wallez59c41592017-07-11 13:19:54 -04002698 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002699 drawBufferIdx++)
2700 {
2701 if (!ValidateWebGLFramebufferAttachmentClearType(
2702 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2703 {
2704 return false;
2705 }
2706 }
2707 }
2708
Olli Etuaho94c91a92018-07-19 15:10:24 +03002709 if (extensions.multiview && extensions.disjointTimerQuery)
2710 {
2711 const State &state = context->getGLState();
2712 Framebuffer *framebuffer = state.getDrawFramebuffer();
2713 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2714 {
Jamie Madill610640f2018-11-21 17:28:41 -05002715 context->validationError(GL_INVALID_OPERATION,
2716 "There is an active query for target "
2717 "GL_TIME_ELAPSED_EXT when the number of "
2718 "views in the active draw framebuffer is "
2719 "greater than 1.");
Olli Etuaho94c91a92018-07-19 15:10:24 +03002720 return false;
2721 }
2722 }
2723
Jamie Madillc29968b2016-01-20 11:17:23 -05002724 return true;
2725}
2726
Jamie Madill5b772312018-03-08 20:28:32 -05002727bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002728{
2729 if (!context->getExtensions().drawBuffers)
2730 {
Jamie Madill610640f2018-11-21 17:28:41 -05002731 context->validationError(GL_INVALID_OPERATION, "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002732 return false;
2733 }
2734
2735 return ValidateDrawBuffersBase(context, n, bufs);
2736}
2737
Jamie Madill73a84962016-02-12 09:27:23 -05002738bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002739 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002740 GLint level,
2741 GLint internalformat,
2742 GLsizei width,
2743 GLsizei height,
2744 GLint border,
2745 GLenum format,
2746 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002747 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002748{
Martin Radev1be913c2016-07-11 17:59:16 +03002749 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002750 {
2751 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002752 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002753 }
2754
Martin Radev1be913c2016-07-11 17:59:16 +03002755 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002756 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002757 0, 0, width, height, 1, border, format, type, -1,
2758 pixels);
2759}
2760
Brandon Jones416aaf92018-04-10 08:10:16 -07002761bool ValidateTexImage2DRobustANGLE(Context *context,
2762 TextureTarget target,
2763 GLint level,
2764 GLint internalformat,
2765 GLsizei width,
2766 GLsizei height,
2767 GLint border,
2768 GLenum format,
2769 GLenum type,
2770 GLsizei bufSize,
2771 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002772{
2773 if (!ValidateRobustEntryPoint(context, bufSize))
2774 {
2775 return false;
2776 }
2777
2778 if (context->getClientMajorVersion() < 3)
2779 {
2780 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2781 0, 0, width, height, border, format, type, bufSize,
2782 pixels);
2783 }
2784
2785 ASSERT(context->getClientMajorVersion() >= 3);
2786 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2787 0, 0, width, height, 1, border, format, type, bufSize,
2788 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002789}
2790
2791bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002792 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002793 GLint level,
2794 GLint xoffset,
2795 GLint yoffset,
2796 GLsizei width,
2797 GLsizei height,
2798 GLenum format,
2799 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002800 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002801{
2802
Martin Radev1be913c2016-07-11 17:59:16 +03002803 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002804 {
2805 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002806 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002807 }
2808
Martin Radev1be913c2016-07-11 17:59:16 +03002809 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002810 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002811 yoffset, 0, width, height, 1, 0, format, type, -1,
2812 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002813}
2814
Geoff Langc52f6f12016-10-14 10:18:00 -04002815bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002816 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002817 GLint level,
2818 GLint xoffset,
2819 GLint yoffset,
2820 GLsizei width,
2821 GLsizei height,
2822 GLenum format,
2823 GLenum type,
2824 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002825 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002826{
2827 if (!ValidateRobustEntryPoint(context, bufSize))
2828 {
2829 return false;
2830 }
2831
2832 if (context->getClientMajorVersion() < 3)
2833 {
2834 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2835 yoffset, width, height, 0, format, type, bufSize,
2836 pixels);
2837 }
2838
2839 ASSERT(context->getClientMajorVersion() >= 3);
2840 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2841 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2842 pixels);
2843}
2844
Jamie Madill73a84962016-02-12 09:27:23 -05002845bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002846 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002847 GLint level,
2848 GLenum internalformat,
2849 GLsizei width,
2850 GLsizei height,
2851 GLint border,
2852 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002853 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002854{
Martin Radev1be913c2016-07-11 17:59:16 +03002855 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002856 {
2857 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002858 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002859 {
2860 return false;
2861 }
2862 }
2863 else
2864 {
Martin Radev1be913c2016-07-11 17:59:16 +03002865 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002866 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002867 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002868 data))
2869 {
2870 return false;
2871 }
2872 }
2873
Geoff Langca271392017-04-05 12:30:00 -04002874 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002875
2876 GLuint blockSize = 0;
2877 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002878 {
Jamie Madille0472f32018-11-27 16:32:45 -05002879 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002880 return false;
2881 }
2882
Jamie Madillca2ff382018-07-11 09:01:17 -04002883 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002884 {
Jamie Madille0472f32018-11-27 16:32:45 -05002885 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002886 return false;
2887 }
2888
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002889 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002890 {
Jamie Madill610640f2018-11-21 17:28:41 -05002891 context->validationError(GL_INVALID_ENUM,
2892 "Rectangle texture cannot have a compressed format.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002893 return false;
2894 }
2895
Jamie Madill73a84962016-02-12 09:27:23 -05002896 return true;
2897}
2898
Corentin Wallezb2931602017-04-11 15:58:57 -04002899bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002900 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002901 GLint level,
2902 GLenum internalformat,
2903 GLsizei width,
2904 GLsizei height,
2905 GLint border,
2906 GLsizei imageSize,
2907 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002908 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002909{
2910 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2911 {
2912 return false;
2913 }
2914
2915 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2916 border, imageSize, data);
2917}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002918
Corentin Wallezb2931602017-04-11 15:58:57 -04002919bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002920 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002921 GLint level,
2922 GLint xoffset,
2923 GLint yoffset,
2924 GLsizei width,
2925 GLsizei height,
2926 GLenum format,
2927 GLsizei imageSize,
2928 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002929 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002930{
2931 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2932 {
2933 return false;
2934 }
2935
2936 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2937 format, imageSize, data);
2938}
2939
Jamie Madill73a84962016-02-12 09:27:23 -05002940bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002941 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002942 GLint level,
2943 GLint xoffset,
2944 GLint yoffset,
2945 GLsizei width,
2946 GLsizei height,
2947 GLenum format,
2948 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002949 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002950{
Martin Radev1be913c2016-07-11 17:59:16 +03002951 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002952 {
2953 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002954 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002955 {
2956 return false;
2957 }
2958 }
2959 else
2960 {
Martin Radev1be913c2016-07-11 17:59:16 +03002961 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002962 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002963 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002964 data))
2965 {
2966 return false;
2967 }
2968 }
2969
Geoff Langca271392017-04-05 12:30:00 -04002970 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002971 GLuint blockSize = 0;
2972 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002973 {
Jamie Madille0472f32018-11-27 16:32:45 -05002974 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002975 return false;
2976 }
2977
Jamie Madillca2ff382018-07-11 09:01:17 -04002978 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002979 {
Jamie Madille0472f32018-11-27 16:32:45 -05002980 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05002981 return false;
2982 }
2983
2984 return true;
2985}
2986
Corentin Wallez336129f2017-10-17 15:55:40 -04002987bool ValidateGetBufferPointervOES(Context *context,
2988 BufferBinding target,
2989 GLenum pname,
2990 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002991{
Geoff Lang496c02d2016-10-20 11:38:11 -07002992 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002993}
2994
Corentin Wallez336129f2017-10-17 15:55:40 -04002995bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002996{
2997 if (!context->getExtensions().mapBuffer)
2998 {
Jamie Madill610640f2018-11-21 17:28:41 -05002999 context->validationError(GL_INVALID_OPERATION, "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003000 return false;
3001 }
3002
Corentin Walleze4477002017-12-01 14:39:58 -05003003 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003004 {
Jamie Madille0472f32018-11-27 16:32:45 -05003005 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003006 return false;
3007 }
3008
Jamie Madilldfde6ab2016-06-09 07:07:18 -07003009 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003010
3011 if (buffer == nullptr)
3012 {
Jamie Madill610640f2018-11-21 17:28:41 -05003013 context->validationError(GL_INVALID_OPERATION, "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003014 return false;
3015 }
3016
3017 if (access != GL_WRITE_ONLY_OES)
3018 {
Jamie Madill610640f2018-11-21 17:28:41 -05003019 context->validationError(GL_INVALID_ENUM, "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003020 return false;
3021 }
3022
3023 if (buffer->isMapped())
3024 {
Jamie Madill610640f2018-11-21 17:28:41 -05003025 context->validationError(GL_INVALID_OPERATION, "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003026 return false;
3027 }
3028
Geoff Lang79f71042017-08-14 16:43:43 -04003029 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003030}
3031
Corentin Wallez336129f2017-10-17 15:55:40 -04003032bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003033{
3034 if (!context->getExtensions().mapBuffer)
3035 {
Jamie Madill610640f2018-11-21 17:28:41 -05003036 context->validationError(GL_INVALID_OPERATION, "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003037 return false;
3038 }
3039
3040 return ValidateUnmapBufferBase(context, target);
3041}
3042
3043bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003044 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003045 GLintptr offset,
3046 GLsizeiptr length,
3047 GLbitfield access)
3048{
3049 if (!context->getExtensions().mapBufferRange)
3050 {
Jamie Madill610640f2018-11-21 17:28:41 -05003051 context->validationError(GL_INVALID_OPERATION, "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003052 return false;
3053 }
3054
3055 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3056}
3057
Corentin Wallez336129f2017-10-17 15:55:40 -04003058bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003059{
3060 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3061 ASSERT(buffer != nullptr);
3062
3063 // Check if this buffer is currently being used as a transform feedback output buffer
3064 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3065 if (transformFeedback != nullptr && transformFeedback->isActive())
3066 {
3067 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3068 {
3069 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3070 if (transformFeedbackBuffer.get() == buffer)
3071 {
Jamie Madill610640f2018-11-21 17:28:41 -05003072 context->validationError(GL_INVALID_OPERATION,
3073 "Buffer is currently bound for transform feedback.");
Geoff Lang79f71042017-08-14 16:43:43 -04003074 return false;
3075 }
3076 }
3077 }
3078
James Darpiniane8a93c62018-01-04 18:02:24 -08003079 if (context->getExtensions().webglCompatibility &&
3080 buffer->isBoundForTransformFeedbackAndOtherUse())
3081 {
Jamie Madille0472f32018-11-27 16:32:45 -05003082 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003083 return false;
3084 }
3085
Geoff Lang79f71042017-08-14 16:43:43 -04003086 return true;
3087}
3088
Olli Etuaho4f667482016-03-30 15:56:35 +03003089bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003090 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003091 GLintptr offset,
3092 GLsizeiptr length)
3093{
3094 if (!context->getExtensions().mapBufferRange)
3095 {
Jamie Madill610640f2018-11-21 17:28:41 -05003096 context->validationError(GL_INVALID_OPERATION, "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003097 return false;
3098 }
3099
3100 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3101}
3102
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003103bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003104{
Jamie Madillac66f982018-10-09 18:30:01 -04003105 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003106 {
Jamie Madillac66f982018-10-09 18:30:01 -04003107 RecordBindTextureTypeError(context, target);
3108 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003109 }
3110
Jamie Madill0fdb9562018-09-17 17:18:43 -04003111 if (texture == 0)
3112 {
3113 return true;
3114 }
3115
3116 Texture *textureObject = context->getTexture(texture);
3117 if (textureObject && textureObject->getType() != target)
3118 {
Jamie Madille0472f32018-11-27 16:32:45 -05003119 context->validationError(GL_INVALID_OPERATION, kTypeMismatch);
Jamie Madill0fdb9562018-09-17 17:18:43 -04003120 return false;
3121 }
3122
3123 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3124 !context->isTextureGenerated(texture))
3125 {
Jamie Madill610640f2018-11-21 17:28:41 -05003126 context->validationError(GL_INVALID_OPERATION, "Texture was not generated");
Jamie Madill0fdb9562018-09-17 17:18:43 -04003127 return false;
3128 }
3129
Ian Ewell54f87462016-03-10 13:47:21 -05003130 return true;
3131}
3132
Geoff Langd8605522016-04-13 10:19:12 -04003133bool ValidateBindUniformLocationCHROMIUM(Context *context,
3134 GLuint program,
3135 GLint location,
3136 const GLchar *name)
3137{
3138 if (!context->getExtensions().bindUniformLocation)
3139 {
Jamie Madill610640f2018-11-21 17:28:41 -05003140 context->validationError(GL_INVALID_OPERATION,
3141 "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003142 return false;
3143 }
3144
3145 Program *programObject = GetValidProgram(context, program);
3146 if (!programObject)
3147 {
3148 return false;
3149 }
3150
3151 if (location < 0)
3152 {
Jamie Madill610640f2018-11-21 17:28:41 -05003153 context->validationError(GL_INVALID_VALUE, "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003154 return false;
3155 }
3156
3157 const Caps &caps = context->getCaps();
3158 if (static_cast<size_t>(location) >=
3159 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3160 {
Jamie Madill610640f2018-11-21 17:28:41 -05003161 context->validationError(GL_INVALID_VALUE,
3162 "Location must be less than "
3163 "(MAX_VERTEX_UNIFORM_VECTORS + "
3164 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003165 return false;
3166 }
3167
Geoff Langfc32e8b2017-05-31 14:16:59 -04003168 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3169 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003170 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003171 {
Jamie Madille0472f32018-11-27 16:32:45 -05003172 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003173 return false;
3174 }
3175
Geoff Langd8605522016-04-13 10:19:12 -04003176 if (strncmp(name, "gl_", 3) == 0)
3177 {
Jamie Madille0472f32018-11-27 16:32:45 -05003178 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003179 return false;
3180 }
3181
3182 return true;
3183}
3184
Jamie Madille2e406c2016-06-02 13:04:10 -04003185bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003186{
3187 if (!context->getExtensions().framebufferMixedSamples)
3188 {
Jamie Madill610640f2018-11-21 17:28:41 -05003189 context->validationError(GL_INVALID_OPERATION,
3190 "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003191 return false;
3192 }
3193 switch (components)
3194 {
3195 case GL_RGB:
3196 case GL_RGBA:
3197 case GL_ALPHA:
3198 case GL_NONE:
3199 break;
3200 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003201 context->validationError(
3202 GL_INVALID_ENUM,
3203 "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003204 return false;
3205 }
3206
3207 return true;
3208}
3209
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210// CHROMIUM_path_rendering
3211
Jamie Madill007530e2017-12-28 14:27:04 -05003212bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003213{
Jamie Madill007530e2017-12-28 14:27:04 -05003214 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003215 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003216 return false;
3217 }
Jamie Madill007530e2017-12-28 14:27:04 -05003218
Sami Väisänene45e53b2016-05-25 10:36:04 +03003219 if (matrix == nullptr)
3220 {
Jamie Madill610640f2018-11-21 17:28:41 -05003221 context->validationError(GL_INVALID_OPERATION, "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003222 return false;
3223 }
Jamie Madill007530e2017-12-28 14:27:04 -05003224
Sami Väisänene45e53b2016-05-25 10:36:04 +03003225 return true;
3226}
3227
Jamie Madill007530e2017-12-28 14:27:04 -05003228bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003229{
Jamie Madill007530e2017-12-28 14:27:04 -05003230 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231}
3232
Jamie Madill007530e2017-12-28 14:27:04 -05003233bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003234{
3235 if (!context->getExtensions().pathRendering)
3236 {
Jamie Madill610640f2018-11-21 17:28:41 -05003237 context->validationError(GL_INVALID_OPERATION,
3238 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003239 return false;
3240 }
3241
3242 // range = 0 is undefined in NV_path_rendering.
3243 // we add stricter semantic check here and require a non zero positive range.
3244 if (range <= 0)
3245 {
Jamie Madille0472f32018-11-27 16:32:45 -05003246 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003247 return false;
3248 }
3249
3250 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3251 {
Jamie Madille0472f32018-11-27 16:32:45 -05003252 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003253 return false;
3254 }
3255
3256 return true;
3257}
3258
Jamie Madill007530e2017-12-28 14:27:04 -05003259bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003260{
3261 if (!context->getExtensions().pathRendering)
3262 {
Jamie Madill610640f2018-11-21 17:28:41 -05003263 context->validationError(GL_INVALID_OPERATION,
3264 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003265 return false;
3266 }
3267
3268 // range = 0 is undefined in NV_path_rendering.
3269 // we add stricter semantic check here and require a non zero positive range.
3270 if (range <= 0)
3271 {
Jamie Madille0472f32018-11-27 16:32:45 -05003272 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003273 return false;
3274 }
3275
3276 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3277 checkedRange += range;
3278
3279 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3280 {
Jamie Madille0472f32018-11-27 16:32:45 -05003281 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
3284 return true;
3285}
3286
Jamie Madill007530e2017-12-28 14:27:04 -05003287bool ValidatePathCommandsCHROMIUM(Context *context,
3288 GLuint path,
3289 GLsizei numCommands,
3290 const GLubyte *commands,
3291 GLsizei numCoords,
3292 GLenum coordType,
3293 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003294{
3295 if (!context->getExtensions().pathRendering)
3296 {
Jamie Madill610640f2018-11-21 17:28:41 -05003297 context->validationError(GL_INVALID_OPERATION,
3298 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003299 return false;
3300 }
Brandon Jones59770802018-04-02 13:18:42 -07003301 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003302 {
Jamie Madille0472f32018-11-27 16:32:45 -05003303 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
3306
3307 if (numCommands < 0)
3308 {
Jamie Madill610640f2018-11-21 17:28:41 -05003309 context->validationError(GL_INVALID_VALUE, "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003310 return false;
3311 }
3312 else if (numCommands > 0)
3313 {
3314 if (!commands)
3315 {
Jamie Madill610640f2018-11-21 17:28:41 -05003316 context->validationError(GL_INVALID_VALUE, "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319 }
3320
3321 if (numCoords < 0)
3322 {
Jamie Madill610640f2018-11-21 17:28:41 -05003323 context->validationError(GL_INVALID_VALUE, "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003324 return false;
3325 }
3326 else if (numCoords > 0)
3327 {
3328 if (!coords)
3329 {
Jamie Madill610640f2018-11-21 17:28:41 -05003330 context->validationError(GL_INVALID_VALUE, "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003331 return false;
3332 }
3333 }
3334
3335 std::uint32_t coordTypeSize = 0;
3336 switch (coordType)
3337 {
3338 case GL_BYTE:
3339 coordTypeSize = sizeof(GLbyte);
3340 break;
3341
3342 case GL_UNSIGNED_BYTE:
3343 coordTypeSize = sizeof(GLubyte);
3344 break;
3345
3346 case GL_SHORT:
3347 coordTypeSize = sizeof(GLshort);
3348 break;
3349
3350 case GL_UNSIGNED_SHORT:
3351 coordTypeSize = sizeof(GLushort);
3352 break;
3353
3354 case GL_FLOAT:
3355 coordTypeSize = sizeof(GLfloat);
3356 break;
3357
3358 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003359 context->validationError(GL_INVALID_ENUM, "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360 return false;
3361 }
3362
3363 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3364 checkedSize += (coordTypeSize * numCoords);
3365 if (!checkedSize.IsValid())
3366 {
Jamie Madille0472f32018-11-27 16:32:45 -05003367 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003368 return false;
3369 }
3370
3371 // early return skips command data validation when it doesn't exist.
3372 if (!commands)
3373 return true;
3374
3375 GLsizei expectedNumCoords = 0;
3376 for (GLsizei i = 0; i < numCommands; ++i)
3377 {
3378 switch (commands[i])
3379 {
3380 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3381 break;
3382 case GL_MOVE_TO_CHROMIUM:
3383 case GL_LINE_TO_CHROMIUM:
3384 expectedNumCoords += 2;
3385 break;
3386 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3387 expectedNumCoords += 4;
3388 break;
3389 case GL_CUBIC_CURVE_TO_CHROMIUM:
3390 expectedNumCoords += 6;
3391 break;
3392 case GL_CONIC_CURVE_TO_CHROMIUM:
3393 expectedNumCoords += 5;
3394 break;
3395 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003396 context->validationError(GL_INVALID_ENUM, "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003397 return false;
3398 }
3399 }
3400 if (expectedNumCoords != numCoords)
3401 {
Jamie Madill610640f2018-11-21 17:28:41 -05003402 context->validationError(GL_INVALID_VALUE, "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003403 return false;
3404 }
3405
3406 return true;
3407}
3408
Jamie Madill007530e2017-12-28 14:27:04 -05003409bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003410{
3411 if (!context->getExtensions().pathRendering)
3412 {
Jamie Madill610640f2018-11-21 17:28:41 -05003413 context->validationError(GL_INVALID_OPERATION,
3414 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003415 return false;
3416 }
Brandon Jones59770802018-04-02 13:18:42 -07003417 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003418 {
Jamie Madille0472f32018-11-27 16:32:45 -05003419 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420 return false;
3421 }
3422
3423 switch (pname)
3424 {
3425 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3426 if (value < 0.0f)
3427 {
Jamie Madill610640f2018-11-21 17:28:41 -05003428 context->validationError(GL_INVALID_VALUE, "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003429 return false;
3430 }
3431 break;
3432 case GL_PATH_END_CAPS_CHROMIUM:
3433 switch (static_cast<GLenum>(value))
3434 {
3435 case GL_FLAT_CHROMIUM:
3436 case GL_SQUARE_CHROMIUM:
3437 case GL_ROUND_CHROMIUM:
3438 break;
3439 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003440 context->validationError(GL_INVALID_ENUM, "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003441 return false;
3442 }
3443 break;
3444 case GL_PATH_JOIN_STYLE_CHROMIUM:
3445 switch (static_cast<GLenum>(value))
3446 {
3447 case GL_MITER_REVERT_CHROMIUM:
3448 case GL_BEVEL_CHROMIUM:
3449 case GL_ROUND_CHROMIUM:
3450 break;
3451 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003452 context->validationError(GL_INVALID_ENUM, "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003453 return false;
3454 }
Nico Weber41b072b2018-02-09 10:01:32 -05003455 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003456 case GL_PATH_MITER_LIMIT_CHROMIUM:
3457 if (value < 0.0f)
3458 {
Jamie Madill610640f2018-11-21 17:28:41 -05003459 context->validationError(GL_INVALID_VALUE, "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003460 return false;
3461 }
3462 break;
3463
3464 case GL_PATH_STROKE_BOUND_CHROMIUM:
3465 // no errors, only clamping.
3466 break;
3467
3468 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003469 context->validationError(GL_INVALID_ENUM, "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003470 return false;
3471 }
3472 return true;
3473}
3474
Jamie Madill007530e2017-12-28 14:27:04 -05003475bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3476{
3477 // TODO(jmadill): Use proper clamping cast.
3478 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3479}
3480
3481bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003482{
3483 if (!context->getExtensions().pathRendering)
3484 {
Jamie Madill610640f2018-11-21 17:28:41 -05003485 context->validationError(GL_INVALID_OPERATION,
3486 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487 return false;
3488 }
3489
Brandon Jones59770802018-04-02 13:18:42 -07003490 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003491 {
Jamie Madille0472f32018-11-27 16:32:45 -05003492 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003493 return false;
3494 }
3495 if (!value)
3496 {
Jamie Madill610640f2018-11-21 17:28:41 -05003497 context->validationError(GL_INVALID_VALUE, "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003498 return false;
3499 }
3500
3501 switch (pname)
3502 {
3503 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3504 case GL_PATH_END_CAPS_CHROMIUM:
3505 case GL_PATH_JOIN_STYLE_CHROMIUM:
3506 case GL_PATH_MITER_LIMIT_CHROMIUM:
3507 case GL_PATH_STROKE_BOUND_CHROMIUM:
3508 break;
3509
3510 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003511 context->validationError(GL_INVALID_ENUM, "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003512 return false;
3513 }
3514
3515 return true;
3516}
3517
Jamie Madill007530e2017-12-28 14:27:04 -05003518bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3519{
3520 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3521 reinterpret_cast<GLfloat *>(value));
3522}
3523
3524bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003525{
3526 if (!context->getExtensions().pathRendering)
3527 {
Jamie Madill610640f2018-11-21 17:28:41 -05003528 context->validationError(GL_INVALID_OPERATION,
3529 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003530 return false;
3531 }
3532
3533 switch (func)
3534 {
3535 case GL_NEVER:
3536 case GL_ALWAYS:
3537 case GL_LESS:
3538 case GL_LEQUAL:
3539 case GL_EQUAL:
3540 case GL_GEQUAL:
3541 case GL_GREATER:
3542 case GL_NOTEQUAL:
3543 break;
3544 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003545 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003546 return false;
3547 }
3548
3549 return true;
3550}
3551
3552// Note that the spec specifies that for the path drawing commands
3553// if the path object is not an existing path object the command
3554// does nothing and no error is generated.
3555// However if the path object exists but has not been specified any
3556// commands then an error is generated.
3557
Jamie Madill007530e2017-12-28 14:27:04 -05003558bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003559{
3560 if (!context->getExtensions().pathRendering)
3561 {
Jamie Madill610640f2018-11-21 17:28:41 -05003562 context->validationError(GL_INVALID_OPERATION,
3563 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003564 return false;
3565 }
Brandon Jones59770802018-04-02 13:18:42 -07003566 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003567 {
Jamie Madille0472f32018-11-27 16:32:45 -05003568 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003569 return false;
3570 }
3571
3572 switch (fillMode)
3573 {
3574 case GL_COUNT_UP_CHROMIUM:
3575 case GL_COUNT_DOWN_CHROMIUM:
3576 break;
3577 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003578 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003579 return false;
3580 }
3581
3582 if (!isPow2(mask + 1))
3583 {
Jamie Madille0472f32018-11-27 16:32:45 -05003584 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003585 return false;
3586 }
3587
3588 return true;
3589}
3590
Jamie Madill007530e2017-12-28 14:27:04 -05003591bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003592{
3593 if (!context->getExtensions().pathRendering)
3594 {
Jamie Madill610640f2018-11-21 17:28:41 -05003595 context->validationError(GL_INVALID_OPERATION,
3596 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003597 return false;
3598 }
Brandon Jones59770802018-04-02 13:18:42 -07003599 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003600 {
Jamie Madill610640f2018-11-21 17:28:41 -05003601 context->validationError(GL_INVALID_OPERATION, "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003602 return false;
3603 }
3604
3605 return true;
3606}
3607
Jamie Madill007530e2017-12-28 14:27:04 -05003608bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003609{
3610 if (!context->getExtensions().pathRendering)
3611 {
Jamie Madill610640f2018-11-21 17:28:41 -05003612 context->validationError(GL_INVALID_OPERATION,
3613 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003614 return false;
3615 }
Brandon Jones59770802018-04-02 13:18:42 -07003616 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003617 {
Jamie Madille0472f32018-11-27 16:32:45 -05003618 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003619 return false;
3620 }
3621
3622 switch (coverMode)
3623 {
3624 case GL_CONVEX_HULL_CHROMIUM:
3625 case GL_BOUNDING_BOX_CHROMIUM:
3626 break;
3627 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003628 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003629 return false;
3630 }
3631 return true;
3632}
3633
Jamie Madill778bf092018-11-14 09:54:36 -05003634bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3635{
3636 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3637}
3638
3639bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3640{
3641 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3642}
3643
Jamie Madill007530e2017-12-28 14:27:04 -05003644bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3645 GLuint path,
3646 GLenum fillMode,
3647 GLuint mask,
3648 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003649{
Jamie Madill007530e2017-12-28 14:27:04 -05003650 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3651 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003652}
3653
Jamie Madill007530e2017-12-28 14:27:04 -05003654bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3655 GLuint path,
3656 GLint reference,
3657 GLuint mask,
3658 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003659{
Jamie Madill007530e2017-12-28 14:27:04 -05003660 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3661 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003662}
3663
Brandon Jonesd1049182018-03-28 10:02:20 -07003664bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003665{
3666 if (!context->getExtensions().pathRendering)
3667 {
Jamie Madill610640f2018-11-21 17:28:41 -05003668 context->validationError(GL_INVALID_OPERATION,
3669 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003670 return false;
3671 }
3672 return true;
3673}
3674
Jamie Madill007530e2017-12-28 14:27:04 -05003675bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3676 GLsizei numPaths,
3677 GLenum pathNameType,
3678 const void *paths,
3679 GLuint pathBase,
3680 GLenum coverMode,
3681 GLenum transformType,
3682 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003683{
3684 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3685 transformType, transformValues))
3686 return false;
3687
3688 switch (coverMode)
3689 {
3690 case GL_CONVEX_HULL_CHROMIUM:
3691 case GL_BOUNDING_BOX_CHROMIUM:
3692 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3693 break;
3694 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003695 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003696 return false;
3697 }
3698
3699 return true;
3700}
3701
Jamie Madill007530e2017-12-28 14:27:04 -05003702bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3703 GLsizei numPaths,
3704 GLenum pathNameType,
3705 const void *paths,
3706 GLuint pathBase,
3707 GLenum coverMode,
3708 GLenum transformType,
3709 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003710{
3711 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3712 transformType, transformValues))
3713 return false;
3714
3715 switch (coverMode)
3716 {
3717 case GL_CONVEX_HULL_CHROMIUM:
3718 case GL_BOUNDING_BOX_CHROMIUM:
3719 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3720 break;
3721 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003722 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003723 return false;
3724 }
3725
3726 return true;
3727}
3728
Jamie Madill007530e2017-12-28 14:27:04 -05003729bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3730 GLsizei numPaths,
3731 GLenum pathNameType,
3732 const void *paths,
3733 GLuint pathBase,
3734 GLenum fillMode,
3735 GLuint mask,
3736 GLenum transformType,
3737 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003738{
3739
3740 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3741 transformType, transformValues))
3742 return false;
3743
3744 switch (fillMode)
3745 {
3746 case GL_COUNT_UP_CHROMIUM:
3747 case GL_COUNT_DOWN_CHROMIUM:
3748 break;
3749 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003750 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003751 return false;
3752 }
3753 if (!isPow2(mask + 1))
3754 {
Jamie Madille0472f32018-11-27 16:32:45 -05003755 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003756 return false;
3757 }
3758 return true;
3759}
3760
Jamie Madill007530e2017-12-28 14:27:04 -05003761bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3762 GLsizei numPaths,
3763 GLenum pathNameType,
3764 const void *paths,
3765 GLuint pathBase,
3766 GLint reference,
3767 GLuint mask,
3768 GLenum transformType,
3769 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003770{
3771 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3772 transformType, transformValues))
3773 return false;
3774
3775 // no more validation here.
3776
3777 return true;
3778}
3779
Jamie Madill007530e2017-12-28 14:27:04 -05003780bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3781 GLsizei numPaths,
3782 GLenum pathNameType,
3783 const void *paths,
3784 GLuint pathBase,
3785 GLenum fillMode,
3786 GLuint mask,
3787 GLenum coverMode,
3788 GLenum transformType,
3789 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003790{
3791 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3792 transformType, transformValues))
3793 return false;
3794
3795 switch (coverMode)
3796 {
3797 case GL_CONVEX_HULL_CHROMIUM:
3798 case GL_BOUNDING_BOX_CHROMIUM:
3799 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3800 break;
3801 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003802 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003803 return false;
3804 }
3805
3806 switch (fillMode)
3807 {
3808 case GL_COUNT_UP_CHROMIUM:
3809 case GL_COUNT_DOWN_CHROMIUM:
3810 break;
3811 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003812 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003813 return false;
3814 }
3815 if (!isPow2(mask + 1))
3816 {
Jamie Madille0472f32018-11-27 16:32:45 -05003817 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003818 return false;
3819 }
3820
3821 return true;
3822}
3823
Jamie Madill007530e2017-12-28 14:27:04 -05003824bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3825 GLsizei numPaths,
3826 GLenum pathNameType,
3827 const void *paths,
3828 GLuint pathBase,
3829 GLint reference,
3830 GLuint mask,
3831 GLenum coverMode,
3832 GLenum transformType,
3833 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003834{
3835 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3836 transformType, transformValues))
3837 return false;
3838
3839 switch (coverMode)
3840 {
3841 case GL_CONVEX_HULL_CHROMIUM:
3842 case GL_BOUNDING_BOX_CHROMIUM:
3843 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3844 break;
3845 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003846 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003847 return false;
3848 }
3849
3850 return true;
3851}
3852
Jamie Madill007530e2017-12-28 14:27:04 -05003853bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3854 GLuint program,
3855 GLint location,
3856 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003857{
3858 if (!context->getExtensions().pathRendering)
3859 {
Jamie Madill610640f2018-11-21 17:28:41 -05003860 context->validationError(GL_INVALID_OPERATION,
3861 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003862 return false;
3863 }
3864
3865 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3866 if (location >= MaxLocation)
3867 {
Jamie Madill610640f2018-11-21 17:28:41 -05003868 context->validationError(GL_INVALID_VALUE, "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003869 return false;
3870 }
3871
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003872 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003873 if (!programObject)
3874 {
Jamie Madille0472f32018-11-27 16:32:45 -05003875 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003876 return false;
3877 }
3878
3879 if (!name)
3880 {
Jamie Madill610640f2018-11-21 17:28:41 -05003881 context->validationError(GL_INVALID_VALUE, "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003882 return false;
3883 }
3884
3885 if (angle::BeginsWith(name, "gl_"))
3886 {
Jamie Madille0472f32018-11-27 16:32:45 -05003887 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003888 return false;
3889 }
3890
3891 return true;
3892}
3893
Jamie Madill007530e2017-12-28 14:27:04 -05003894bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3895 GLuint program,
3896 GLint location,
3897 GLenum genMode,
3898 GLint components,
3899 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003900{
3901 if (!context->getExtensions().pathRendering)
3902 {
Jamie Madill610640f2018-11-21 17:28:41 -05003903 context->validationError(GL_INVALID_OPERATION,
3904 "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003905 return false;
3906 }
3907
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003908 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003909 if (!programObject || programObject->isFlaggedForDeletion())
3910 {
Jamie Madille0472f32018-11-27 16:32:45 -05003911 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003912 return false;
3913 }
3914
3915 if (!programObject->isLinked())
3916 {
Jamie Madille0472f32018-11-27 16:32:45 -05003917 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003918 return false;
3919 }
3920
3921 switch (genMode)
3922 {
3923 case GL_NONE:
3924 if (components != 0)
3925 {
Jamie Madill610640f2018-11-21 17:28:41 -05003926 context->validationError(GL_INVALID_VALUE, "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003927 return false;
3928 }
3929 break;
3930
3931 case GL_OBJECT_LINEAR_CHROMIUM:
3932 case GL_EYE_LINEAR_CHROMIUM:
3933 case GL_CONSTANT_CHROMIUM:
3934 if (components < 1 || components > 4)
3935 {
Jamie Madill610640f2018-11-21 17:28:41 -05003936 context->validationError(GL_INVALID_VALUE, "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003937 return false;
3938 }
3939 if (!coeffs)
3940 {
Jamie Madill610640f2018-11-21 17:28:41 -05003941 context->validationError(GL_INVALID_VALUE, "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003942 return false;
3943 }
3944 break;
3945
3946 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003947 context->validationError(GL_INVALID_ENUM, "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003948 return false;
3949 }
3950
3951 // If the location is -1 then the command is silently ignored
3952 // and no further validation is needed.
3953 if (location == -1)
3954 return true;
3955
jchen103fd614d2018-08-13 12:21:58 +08003956 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003957
3958 if (!binding.valid)
3959 {
Jamie Madill610640f2018-11-21 17:28:41 -05003960 context->validationError(GL_INVALID_OPERATION, "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003961 return false;
3962 }
3963
3964 if (binding.type != GL_NONE)
3965 {
3966 GLint expectedComponents = 0;
3967 switch (binding.type)
3968 {
3969 case GL_FLOAT:
3970 expectedComponents = 1;
3971 break;
3972 case GL_FLOAT_VEC2:
3973 expectedComponents = 2;
3974 break;
3975 case GL_FLOAT_VEC3:
3976 expectedComponents = 3;
3977 break;
3978 case GL_FLOAT_VEC4:
3979 expectedComponents = 4;
3980 break;
3981 default:
Jamie Madill610640f2018-11-21 17:28:41 -05003982 context->validationError(
3983 GL_INVALID_OPERATION,
3984 "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003985 return false;
3986 }
3987 if (expectedComponents != components && genMode != GL_NONE)
3988 {
Jamie Madill610640f2018-11-21 17:28:41 -05003989 context->validationError(GL_INVALID_OPERATION, "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003990 return false;
3991 }
3992 }
3993 return true;
3994}
3995
Geoff Lang97073d12016-04-20 10:42:34 -07003996bool ValidateCopyTextureCHROMIUM(Context *context,
3997 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003998 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003999 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004000 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004001 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004002 GLint internalFormat,
4003 GLenum destType,
4004 GLboolean unpackFlipY,
4005 GLboolean unpackPremultiplyAlpha,
4006 GLboolean unpackUnmultiplyAlpha)
4007{
4008 if (!context->getExtensions().copyTexture)
4009 {
Jamie Madill610640f2018-11-21 17:28:41 -05004010 context->validationError(GL_INVALID_OPERATION,
4011 "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004012 return false;
4013 }
4014
Geoff Lang4f0e0032017-05-01 16:04:35 -04004015 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004016 if (source == nullptr)
4017 {
Jamie Madill610640f2018-11-21 17:28:41 -05004018 context->validationError(GL_INVALID_VALUE, "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004019 return false;
4020 }
4021
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004022 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004023 {
Jamie Madille0472f32018-11-27 16:32:45 -05004024 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004025 return false;
4026 }
4027
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004028 TextureType sourceType = source->getType();
4029 ASSERT(sourceType != TextureType::CubeMap);
4030 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004031
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004032 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004033 {
Jamie Madill610640f2018-11-21 17:28:41 -05004034 context->validationError(GL_INVALID_VALUE, "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004035 return false;
4036 }
4037
Geoff Lang4f0e0032017-05-01 16:04:35 -04004038 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4039 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4040 if (sourceWidth == 0 || sourceHeight == 0)
4041 {
Jamie Madille0472f32018-11-27 16:32:45 -05004042 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004043 return false;
4044 }
4045
4046 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4047 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004048 {
Jamie Madill610640f2018-11-21 17:28:41 -05004049 context->validationError(GL_INVALID_OPERATION,
4050 "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004051 return false;
4052 }
4053
Geoff Lang63458a32017-10-30 15:16:53 -04004054 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4055 {
Jamie Madille0472f32018-11-27 16:32:45 -05004056 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004057 return false;
4058 }
4059
Geoff Lang4f0e0032017-05-01 16:04:35 -04004060 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004061 if (dest == nullptr)
4062 {
Jamie Madill610640f2018-11-21 17:28:41 -05004063 context->validationError(GL_INVALID_VALUE,
4064 "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004065 return false;
4066 }
4067
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004068 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004069 {
Jamie Madill610640f2018-11-21 17:28:41 -05004070 context->validationError(GL_INVALID_VALUE, "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004071 return false;
4072 }
4073
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004074 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004075 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004076 {
Jamie Madille0472f32018-11-27 16:32:45 -05004077 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004078 return false;
4079 }
4080
Geoff Lang97073d12016-04-20 10:42:34 -07004081 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4082 {
Geoff Lang97073d12016-04-20 10:42:34 -07004083 return false;
4084 }
4085
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004086 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004087 {
Jamie Madill610640f2018-11-21 17:28:41 -05004088 context->validationError(
4089 GL_INVALID_VALUE, "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004090 return false;
4091 }
4092
Geoff Lang97073d12016-04-20 10:42:34 -07004093 if (dest->getImmutableFormat())
4094 {
Jamie Madill610640f2018-11-21 17:28:41 -05004095 context->validationError(GL_INVALID_OPERATION, "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004096 return false;
4097 }
4098
4099 return true;
4100}
4101
4102bool ValidateCopySubTextureCHROMIUM(Context *context,
4103 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004104 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004105 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004106 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004107 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004108 GLint xoffset,
4109 GLint yoffset,
4110 GLint x,
4111 GLint y,
4112 GLsizei width,
4113 GLsizei height,
4114 GLboolean unpackFlipY,
4115 GLboolean unpackPremultiplyAlpha,
4116 GLboolean unpackUnmultiplyAlpha)
4117{
4118 if (!context->getExtensions().copyTexture)
4119 {
Jamie Madill610640f2018-11-21 17:28:41 -05004120 context->validationError(GL_INVALID_OPERATION,
4121 "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004122 return false;
4123 }
4124
Geoff Lang4f0e0032017-05-01 16:04:35 -04004125 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004126 if (source == nullptr)
4127 {
Jamie Madill610640f2018-11-21 17:28:41 -05004128 context->validationError(GL_INVALID_VALUE, "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004129 return false;
4130 }
4131
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004132 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004133 {
Jamie Madill610640f2018-11-21 17:28:41 -05004134 context->validationError(GL_INVALID_VALUE, "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004135 return false;
4136 }
4137
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004138 TextureType sourceType = source->getType();
4139 ASSERT(sourceType != TextureType::CubeMap);
4140 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004141
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004142 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004143 {
Jamie Madille0472f32018-11-27 16:32:45 -05004144 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004145 return false;
4146 }
4147
4148 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4149 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004150 {
Jamie Madill610640f2018-11-21 17:28:41 -05004151 context->validationError(GL_INVALID_VALUE,
4152 "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004153 return false;
4154 }
4155
4156 if (x < 0 || y < 0)
4157 {
Jamie Madill610640f2018-11-21 17:28:41 -05004158 context->validationError(GL_INVALID_VALUE, "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004159 return false;
4160 }
4161
4162 if (width < 0 || height < 0)
4163 {
Jamie Madille0472f32018-11-27 16:32:45 -05004164 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004165 return false;
4166 }
4167
Geoff Lang4f0e0032017-05-01 16:04:35 -04004168 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4169 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004170 {
Jamie Madille0472f32018-11-27 16:32:45 -05004171 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004172 return false;
4173 }
4174
Geoff Lang4f0e0032017-05-01 16:04:35 -04004175 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4176 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004177 {
Jamie Madille0472f32018-11-27 16:32:45 -05004178 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004179 return false;
4180 }
4181
Geoff Lang63458a32017-10-30 15:16:53 -04004182 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4183 {
Jamie Madille0472f32018-11-27 16:32:45 -05004184 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004185 return false;
4186 }
4187
Geoff Lang4f0e0032017-05-01 16:04:35 -04004188 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004189 if (dest == nullptr)
4190 {
Jamie Madill610640f2018-11-21 17:28:41 -05004191 context->validationError(GL_INVALID_VALUE,
4192 "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004193 return false;
4194 }
4195
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004196 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004197 {
Jamie Madill610640f2018-11-21 17:28:41 -05004198 context->validationError(GL_INVALID_VALUE, "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004199 return false;
4200 }
4201
Brandon Jones28783792018-03-05 09:37:32 -08004202 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4203 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004204 {
Jamie Madill610640f2018-11-21 17:28:41 -05004205 context->validationError(GL_INVALID_VALUE, "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004206 return false;
4207 }
4208
Geoff Lang4f0e0032017-05-01 16:04:35 -04004209 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4210 {
Jamie Madill610640f2018-11-21 17:28:41 -05004211 context->validationError(
4212 GL_INVALID_OPERATION,
4213 "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004214 return false;
4215 }
4216
4217 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4218 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004219 {
Jamie Madill610640f2018-11-21 17:28:41 -05004220 context->validationError(GL_INVALID_OPERATION,
4221 "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004222 return false;
4223 }
4224
4225 if (xoffset < 0 || yoffset < 0)
4226 {
Jamie Madille0472f32018-11-27 16:32:45 -05004227 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004228 return false;
4229 }
4230
Geoff Lang4f0e0032017-05-01 16:04:35 -04004231 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4232 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004233 {
Jamie Madill610640f2018-11-21 17:28:41 -05004234 context->validationError(GL_INVALID_VALUE,
4235 "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004236 return false;
4237 }
4238
4239 return true;
4240}
4241
Geoff Lang47110bf2016-04-20 11:13:22 -07004242bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4243{
4244 if (!context->getExtensions().copyCompressedTexture)
4245 {
Jamie Madill610640f2018-11-21 17:28:41 -05004246 context->validationError(GL_INVALID_OPERATION,
4247 "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004248 return false;
4249 }
4250
4251 const gl::Texture *source = context->getTexture(sourceId);
4252 if (source == nullptr)
4253 {
Jamie Madill610640f2018-11-21 17:28:41 -05004254 context->validationError(GL_INVALID_VALUE, "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004255 return false;
4256 }
4257
Corentin Wallez99d492c2018-02-27 15:17:10 -05004258 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004259 {
Jamie Madill610640f2018-11-21 17:28:41 -05004260 context->validationError(GL_INVALID_VALUE, "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004261 return false;
4262 }
4263
Corentin Wallez99d492c2018-02-27 15:17:10 -05004264 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4265 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004266 {
Jamie Madill610640f2018-11-21 17:28:41 -05004267 context->validationError(GL_INVALID_VALUE, "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004268 return false;
4269 }
4270
Corentin Wallez99d492c2018-02-27 15:17:10 -05004271 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004272 if (!sourceFormat.info->compressed)
4273 {
Jamie Madill610640f2018-11-21 17:28:41 -05004274 context->validationError(GL_INVALID_OPERATION,
4275 "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004276 return false;
4277 }
4278
4279 const gl::Texture *dest = context->getTexture(destId);
4280 if (dest == nullptr)
4281 {
Jamie Madill610640f2018-11-21 17:28:41 -05004282 context->validationError(GL_INVALID_VALUE,
4283 "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004284 return false;
4285 }
4286
Corentin Wallez99d492c2018-02-27 15:17:10 -05004287 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004288 {
Jamie Madill610640f2018-11-21 17:28:41 -05004289 context->validationError(GL_INVALID_VALUE,
4290 "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004291 return false;
4292 }
4293
4294 if (dest->getImmutableFormat())
4295 {
Jamie Madill610640f2018-11-21 17:28:41 -05004296 context->validationError(GL_INVALID_OPERATION, "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004297 return false;
4298 }
4299
4300 return true;
4301}
4302
Jiawei Shao385b3e02018-03-21 09:43:28 +08004303bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004304{
4305 switch (type)
4306 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004307 case ShaderType::Vertex:
4308 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004309 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004310
Jiawei Shao385b3e02018-03-21 09:43:28 +08004311 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004312 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004313 {
Jamie Madille0472f32018-11-27 16:32:45 -05004314 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004315 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004316 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004317 break;
4318
Jiawei Shao385b3e02018-03-21 09:43:28 +08004319 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004320 if (!context->getExtensions().geometryShader)
4321 {
Jamie Madille0472f32018-11-27 16:32:45 -05004322 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004323 return false;
4324 }
4325 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004326 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004327 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004328 return false;
4329 }
Jamie Madill29639852016-09-02 15:00:09 -04004330
4331 return true;
4332}
4333
Jamie Madill5b772312018-03-08 20:28:32 -05004334bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004335 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004336 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004337 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004338 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004339{
4340 if (size < 0)
4341 {
Jamie Madille0472f32018-11-27 16:32:45 -05004342 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004343 return false;
4344 }
4345
4346 switch (usage)
4347 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004348 case BufferUsage::StreamDraw:
4349 case BufferUsage::StaticDraw:
4350 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004351 break;
4352
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004353 case BufferUsage::StreamRead:
4354 case BufferUsage::StaticRead:
4355 case BufferUsage::DynamicRead:
4356 case BufferUsage::StreamCopy:
4357 case BufferUsage::StaticCopy:
4358 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004359 if (context->getClientMajorVersion() < 3)
4360 {
Jamie Madille0472f32018-11-27 16:32:45 -05004361 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004362 return false;
4363 }
4364 break;
4365
4366 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004367 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004368 return false;
4369 }
4370
Corentin Walleze4477002017-12-01 14:39:58 -05004371 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004372 {
Jamie Madille0472f32018-11-27 16:32:45 -05004373 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004374 return false;
4375 }
4376
4377 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4378
4379 if (!buffer)
4380 {
Jamie Madille0472f32018-11-27 16:32:45 -05004381 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004382 return false;
4383 }
4384
James Darpiniane8a93c62018-01-04 18:02:24 -08004385 if (context->getExtensions().webglCompatibility &&
4386 buffer->isBoundForTransformFeedbackAndOtherUse())
4387 {
Jamie Madille0472f32018-11-27 16:32:45 -05004388 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004389 return false;
4390 }
4391
Jamie Madill29639852016-09-02 15:00:09 -04004392 return true;
4393}
4394
Jamie Madill5b772312018-03-08 20:28:32 -05004395bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004396 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004397 GLintptr offset,
4398 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004399 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004400{
Brandon Jones6cad5662017-06-14 13:25:13 -07004401 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004402 {
Jamie Madille0472f32018-11-27 16:32:45 -05004403 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004404 return false;
4405 }
4406
4407 if (offset < 0)
4408 {
Jamie Madille0472f32018-11-27 16:32:45 -05004409 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004410 return false;
4411 }
4412
Corentin Walleze4477002017-12-01 14:39:58 -05004413 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004414 {
Jamie Madille0472f32018-11-27 16:32:45 -05004415 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004416 return false;
4417 }
4418
4419 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4420
4421 if (!buffer)
4422 {
Jamie Madille0472f32018-11-27 16:32:45 -05004423 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004424 return false;
4425 }
4426
4427 if (buffer->isMapped())
4428 {
Jamie Madille0472f32018-11-27 16:32:45 -05004429 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004430 return false;
4431 }
4432
James Darpiniane8a93c62018-01-04 18:02:24 -08004433 if (context->getExtensions().webglCompatibility &&
4434 buffer->isBoundForTransformFeedbackAndOtherUse())
4435 {
Jamie Madille0472f32018-11-27 16:32:45 -05004436 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004437 return false;
4438 }
4439
Jamie Madill29639852016-09-02 15:00:09 -04004440 // Check for possible overflow of size + offset
4441 angle::CheckedNumeric<size_t> checkedSize(size);
4442 checkedSize += offset;
4443 if (!checkedSize.IsValid())
4444 {
Jamie Madille0472f32018-11-27 16:32:45 -05004445 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004446 return false;
4447 }
4448
4449 if (size + offset > buffer->getSize())
4450 {
Jamie Madille0472f32018-11-27 16:32:45 -05004451 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004452 return false;
4453 }
4454
Martin Radev4c4c8e72016-08-04 12:25:34 +03004455 return true;
4456}
4457
Geoff Lang111a99e2017-10-17 10:58:41 -04004458bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004459{
Geoff Langc339c4e2016-11-29 10:37:36 -05004460 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004461 {
Jamie Madill610640f2018-11-21 17:28:41 -05004462 context->validationError(GL_INVALID_OPERATION,
4463 "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004464 return false;
4465 }
4466
Geoff Lang111a99e2017-10-17 10:58:41 -04004467 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004468 {
Jamie Madill610640f2018-11-21 17:28:41 -05004469 context->validationError(GL_INVALID_OPERATION, "Extension is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004470 return false;
4471 }
4472
4473 return true;
4474}
4475
Jamie Madill5b772312018-03-08 20:28:32 -05004476bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004477{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004478 if (context->getClientMajorVersion() < 2)
4479 {
4480 return ValidateMultitextureUnit(context, texture);
4481 }
4482
Jamie Madillef300b12016-10-07 15:12:09 -04004483 if (texture < GL_TEXTURE0 ||
4484 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4485 {
Jamie Madille0472f32018-11-27 16:32:45 -05004486 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004487 return false;
4488 }
4489
4490 return true;
4491}
4492
Jamie Madill5b772312018-03-08 20:28:32 -05004493bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004494{
4495 Program *programObject = GetValidProgram(context, program);
4496 if (!programObject)
4497 {
4498 return false;
4499 }
4500
4501 Shader *shaderObject = GetValidShader(context, shader);
4502 if (!shaderObject)
4503 {
4504 return false;
4505 }
4506
Jiawei Shao385b3e02018-03-21 09:43:28 +08004507 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004508 {
Jamie Madille0472f32018-11-27 16:32:45 -05004509 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004510 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004511 }
4512
4513 return true;
4514}
4515
Jamie Madill5b772312018-03-08 20:28:32 -05004516bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004517{
4518 if (index >= MAX_VERTEX_ATTRIBS)
4519 {
Jamie Madille0472f32018-11-27 16:32:45 -05004520 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004521 return false;
4522 }
4523
4524 if (strncmp(name, "gl_", 3) == 0)
4525 {
Jamie Madille0472f32018-11-27 16:32:45 -05004526 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004527 return false;
4528 }
4529
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004530 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004531 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004532 const size_t length = strlen(name);
4533
4534 if (!IsValidESSLString(name, length))
4535 {
4536 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4537 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004538 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004539 return false;
4540 }
4541
4542 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4543 {
4544 return false;
4545 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004546 }
4547
Jamie Madill01a80ee2016-11-07 12:06:18 -05004548 return GetValidProgram(context, program) != nullptr;
4549}
4550
Jamie Madill5b772312018-03-08 20:28:32 -05004551bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004552{
Geoff Lange8afa902017-09-27 15:00:43 -04004553 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004554 {
Jamie Madille0472f32018-11-27 16:32:45 -05004555 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004556 return false;
4557 }
4558
4559 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4560 !context->isFramebufferGenerated(framebuffer))
4561 {
Jamie Madille0472f32018-11-27 16:32:45 -05004562 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004563 return false;
4564 }
4565
4566 return true;
4567}
4568
Jamie Madill5b772312018-03-08 20:28:32 -05004569bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004570{
4571 if (target != GL_RENDERBUFFER)
4572 {
Jamie Madille0472f32018-11-27 16:32:45 -05004573 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004574 return false;
4575 }
4576
4577 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4578 !context->isRenderbufferGenerated(renderbuffer))
4579 {
Jamie Madille0472f32018-11-27 16:32:45 -05004580 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004581 return false;
4582 }
4583
4584 return true;
4585}
4586
Jamie Madill5b772312018-03-08 20:28:32 -05004587static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004588{
4589 switch (mode)
4590 {
4591 case GL_FUNC_ADD:
4592 case GL_FUNC_SUBTRACT:
4593 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004594 return true;
4595
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004596 case GL_MIN:
4597 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004598 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004599
4600 default:
4601 return false;
4602 }
4603}
4604
Jamie Madill5b772312018-03-08 20:28:32 -05004605bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004606{
4607 return true;
4608}
4609
Jamie Madill5b772312018-03-08 20:28:32 -05004610bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004611{
Geoff Lang50cac572017-09-26 17:37:43 -04004612 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 {
Jamie Madille0472f32018-11-27 16:32:45 -05004614 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004615 return false;
4616 }
4617
4618 return true;
4619}
4620
Jamie Madill5b772312018-03-08 20:28:32 -05004621bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004622{
Geoff Lang50cac572017-09-26 17:37:43 -04004623 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004624 {
Jamie Madille0472f32018-11-27 16:32:45 -05004625 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 return false;
4627 }
4628
Geoff Lang50cac572017-09-26 17:37:43 -04004629 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004630 {
Jamie Madille0472f32018-11-27 16:32:45 -05004631 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004632 return false;
4633 }
4634
4635 return true;
4636}
4637
Jamie Madill5b772312018-03-08 20:28:32 -05004638bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639{
4640 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4641}
4642
Jamie Madill5b772312018-03-08 20:28:32 -05004643bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004644 GLenum srcRGB,
4645 GLenum dstRGB,
4646 GLenum srcAlpha,
4647 GLenum dstAlpha)
4648{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004649 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004650 {
Jamie Madille0472f32018-11-27 16:32:45 -05004651 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004652 return false;
4653 }
4654
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004655 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004656 {
Jamie Madille0472f32018-11-27 16:32:45 -05004657 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004658 return false;
4659 }
4660
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004661 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004662 {
Jamie Madille0472f32018-11-27 16:32:45 -05004663 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004664 return false;
4665 }
4666
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004667 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004668 {
Jamie Madille0472f32018-11-27 16:32:45 -05004669 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004670 return false;
4671 }
4672
Frank Henigman146e8a12017-03-02 23:22:37 -05004673 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4674 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004675 {
4676 bool constantColorUsed =
4677 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4678 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4679
4680 bool constantAlphaUsed =
4681 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4682 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4683
4684 if (constantColorUsed && constantAlphaUsed)
4685 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004686 const char *msg;
4687 if (context->getExtensions().webglCompatibility)
4688 {
Jamie Madille0472f32018-11-27 16:32:45 -05004689 msg = kInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004690 }
4691 else
4692 {
4693 msg =
4694 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4695 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4696 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004697 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004698 }
Jamie Madill610640f2018-11-21 17:28:41 -05004699 context->validationError(GL_INVALID_OPERATION, msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004700 return false;
4701 }
4702 }
4703
4704 return true;
4705}
4706
Geoff Langc339c4e2016-11-29 10:37:36 -05004707bool ValidateGetString(Context *context, GLenum name)
4708{
4709 switch (name)
4710 {
4711 case GL_VENDOR:
4712 case GL_RENDERER:
4713 case GL_VERSION:
4714 case GL_SHADING_LANGUAGE_VERSION:
4715 case GL_EXTENSIONS:
4716 break;
4717
4718 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4719 if (!context->getExtensions().requestExtension)
4720 {
Jamie Madille0472f32018-11-27 16:32:45 -05004721 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004722 return false;
4723 }
4724 break;
4725
4726 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004727 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004728 return false;
4729 }
4730
4731 return true;
4732}
4733
Jamie Madill5b772312018-03-08 20:28:32 -05004734bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004735{
4736 if (width <= 0.0f || isNaN(width))
4737 {
Jamie Madille0472f32018-11-27 16:32:45 -05004738 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004739 return false;
4740 }
4741
4742 return true;
4743}
4744
Jamie Madill5b772312018-03-08 20:28:32 -05004745bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004746 GLuint index,
4747 GLint size,
4748 GLenum type,
4749 GLboolean normalized,
4750 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004751 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004752{
Shao80957d92017-02-20 21:25:59 +08004753 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004755 return false;
4756 }
4757
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 if (stride < 0)
4759 {
Jamie Madille0472f32018-11-27 16:32:45 -05004760 context->validationError(GL_INVALID_VALUE, kNegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004761 return false;
4762 }
4763
Shao80957d92017-02-20 21:25:59 +08004764 const Caps &caps = context->getCaps();
4765 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004766 {
Shao80957d92017-02-20 21:25:59 +08004767 if (stride > caps.maxVertexAttribStride)
4768 {
Jamie Madill610640f2018-11-21 17:28:41 -05004769 context->validationError(GL_INVALID_VALUE,
4770 "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004771 return false;
4772 }
4773
4774 if (index >= caps.maxVertexAttribBindings)
4775 {
Jamie Madill610640f2018-11-21 17:28:41 -05004776 context->validationError(GL_INVALID_VALUE,
4777 "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004778 return false;
4779 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004780 }
4781
4782 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4783 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4784 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4785 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004786 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4787 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004788 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4789 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004790 {
Jamie Madill610640f2018-11-21 17:28:41 -05004791 context->validationError(
4792 GL_INVALID_OPERATION,
4793 "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004794 return false;
4795 }
4796
4797 if (context->getExtensions().webglCompatibility)
4798 {
4799 // WebGL 1.0 [Section 6.14] Fixed point support
4800 // The WebGL API does not support the GL_FIXED data type.
4801 if (type == GL_FIXED)
4802 {
Jamie Madill610640f2018-11-21 17:28:41 -05004803 context->validationError(GL_INVALID_ENUM, "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004804 return false;
4805 }
4806
Geoff Lang2d62ab72017-03-23 16:54:40 -04004807 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004808 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004809 return false;
4810 }
4811 }
4812
4813 return true;
4814}
4815
Jamie Madill5b772312018-03-08 20:28:32 -05004816bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004817{
4818 if (context->getExtensions().webglCompatibility && zNear > zFar)
4819 {
Jamie Madille0472f32018-11-27 16:32:45 -05004820 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004821 return false;
4822 }
4823
4824 return true;
4825}
4826
Jamie Madill5b772312018-03-08 20:28:32 -05004827bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004828 GLenum target,
4829 GLenum internalformat,
4830 GLsizei width,
4831 GLsizei height)
4832{
4833 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4834 height);
4835}
4836
Jamie Madill5b772312018-03-08 20:28:32 -05004837bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004838 GLenum target,
4839 GLsizei samples,
4840 GLenum internalformat,
4841 GLsizei width,
4842 GLsizei height)
4843{
4844 if (!context->getExtensions().framebufferMultisample)
4845 {
Jamie Madill610640f2018-11-21 17:28:41 -05004846 context->validationError(GL_INVALID_OPERATION,
4847 "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004848 return false;
4849 }
4850
4851 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05004852 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05004853 // generated.
4854 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4855 {
Jamie Madille0472f32018-11-27 16:32:45 -05004856 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004857 return false;
4858 }
4859
4860 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4861 // the specified storage. This is different than ES 3.0 in which a sample number higher
4862 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4863 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4864 if (context->getClientMajorVersion() >= 3)
4865 {
4866 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4867 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4868 {
Jamie Madille0472f32018-11-27 16:32:45 -05004869 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05004870 return false;
4871 }
4872 }
4873
4874 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4875 width, height);
4876}
4877
Jamie Madill5b772312018-03-08 20:28:32 -05004878bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004879{
Geoff Lange8afa902017-09-27 15:00:43 -04004880 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004881 {
Jamie Madille0472f32018-11-27 16:32:45 -05004882 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004883 return false;
4884 }
4885
4886 return true;
4887}
4888
Jamie Madill5b772312018-03-08 20:28:32 -05004889bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004890{
4891 return true;
4892}
4893
Jamie Madill5b772312018-03-08 20:28:32 -05004894bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895{
4896 return true;
4897}
4898
Jamie Madill5b772312018-03-08 20:28:32 -05004899bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900{
4901 return true;
4902}
4903
Jamie Madill5b772312018-03-08 20:28:32 -05004904bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905 GLboolean red,
4906 GLboolean green,
4907 GLboolean blue,
4908 GLboolean alpha)
4909{
4910 return true;
4911}
4912
Jamie Madill5b772312018-03-08 20:28:32 -05004913bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004914{
4915 return true;
4916}
4917
Jamie Madill5b772312018-03-08 20:28:32 -05004918bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919{
4920 return true;
4921}
4922
Jamie Madill5b772312018-03-08 20:28:32 -05004923bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004924{
4925 switch (mode)
4926 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004927 case CullFaceMode::Front:
4928 case CullFaceMode::Back:
4929 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004930 break;
4931
4932 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004933 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004934 return false;
4935 }
4936
4937 return true;
4938}
4939
Jamie Madill5b772312018-03-08 20:28:32 -05004940bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004941{
4942 if (program == 0)
4943 {
4944 return false;
4945 }
4946
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004947 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004948 {
4949 if (context->getShader(program))
4950 {
Jamie Madille0472f32018-11-27 16:32:45 -05004951 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004952 return false;
4953 }
4954 else
4955 {
Jamie Madille0472f32018-11-27 16:32:45 -05004956 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004957 return false;
4958 }
4959 }
4960
4961 return true;
4962}
4963
Jamie Madill5b772312018-03-08 20:28:32 -05004964bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004965{
4966 if (shader == 0)
4967 {
4968 return false;
4969 }
4970
4971 if (!context->getShader(shader))
4972 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004973 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004974 {
Jamie Madille0472f32018-11-27 16:32:45 -05004975 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976 return false;
4977 }
4978 else
4979 {
Jamie Madille0472f32018-11-27 16:32:45 -05004980 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004981 return false;
4982 }
4983 }
4984
4985 return true;
4986}
4987
Jamie Madill5b772312018-03-08 20:28:32 -05004988bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004989{
4990 switch (func)
4991 {
4992 case GL_NEVER:
4993 case GL_ALWAYS:
4994 case GL_LESS:
4995 case GL_LEQUAL:
4996 case GL_EQUAL:
4997 case GL_GREATER:
4998 case GL_GEQUAL:
4999 case GL_NOTEQUAL:
5000 break;
5001
5002 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005003 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005004 return false;
5005 }
5006
5007 return true;
5008}
5009
Jamie Madill5b772312018-03-08 20:28:32 -05005010bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005011{
5012 return true;
5013}
5014
Jamie Madill5b772312018-03-08 20:28:32 -05005015bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005016{
5017 Program *programObject = GetValidProgram(context, program);
5018 if (!programObject)
5019 {
5020 return false;
5021 }
5022
5023 Shader *shaderObject = GetValidShader(context, shader);
5024 if (!shaderObject)
5025 {
5026 return false;
5027 }
5028
Jiawei Shao385b3e02018-03-21 09:43:28 +08005029 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005030 if (attachedShader != shaderObject)
5031 {
Jamie Madille0472f32018-11-27 16:32:45 -05005032 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033 return false;
5034 }
5035
5036 return true;
5037}
5038
Jamie Madill5b772312018-03-08 20:28:32 -05005039bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005040{
5041 if (index >= MAX_VERTEX_ATTRIBS)
5042 {
Jamie Madille0472f32018-11-27 16:32:45 -05005043 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005044 return false;
5045 }
5046
5047 return true;
5048}
5049
Jamie Madill5b772312018-03-08 20:28:32 -05005050bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051{
5052 if (index >= MAX_VERTEX_ATTRIBS)
5053 {
Jamie Madille0472f32018-11-27 16:32:45 -05005054 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005055 return false;
5056 }
5057
5058 return true;
5059}
5060
Jamie Madill5b772312018-03-08 20:28:32 -05005061bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062{
5063 return true;
5064}
5065
Jamie Madill5b772312018-03-08 20:28:32 -05005066bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005067{
5068 return true;
5069}
5070
Jamie Madill5b772312018-03-08 20:28:32 -05005071bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005072{
5073 switch (mode)
5074 {
5075 case GL_CW:
5076 case GL_CCW:
5077 break;
5078 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005079 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005080 return false;
5081 }
5082
5083 return true;
5084}
5085
Jamie Madill5b772312018-03-08 20:28:32 -05005086bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 GLuint program,
5088 GLuint index,
5089 GLsizei bufsize,
5090 GLsizei *length,
5091 GLint *size,
5092 GLenum *type,
5093 GLchar *name)
5094{
5095 if (bufsize < 0)
5096 {
Jamie Madille0472f32018-11-27 16:32:45 -05005097 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005098 return false;
5099 }
5100
5101 Program *programObject = GetValidProgram(context, program);
5102
5103 if (!programObject)
5104 {
5105 return false;
5106 }
5107
5108 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5109 {
Jamie Madille0472f32018-11-27 16:32:45 -05005110 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005111 return false;
5112 }
5113
5114 return true;
5115}
5116
Jamie Madill5b772312018-03-08 20:28:32 -05005117bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005118 GLuint program,
5119 GLuint index,
5120 GLsizei bufsize,
5121 GLsizei *length,
5122 GLint *size,
5123 GLenum *type,
5124 GLchar *name)
5125{
5126 if (bufsize < 0)
5127 {
Jamie Madille0472f32018-11-27 16:32:45 -05005128 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005129 return false;
5130 }
5131
5132 Program *programObject = GetValidProgram(context, program);
5133
5134 if (!programObject)
5135 {
5136 return false;
5137 }
5138
5139 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5140 {
Jamie Madille0472f32018-11-27 16:32:45 -05005141 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005142 return false;
5143 }
5144
5145 return true;
5146}
5147
Jamie Madill5b772312018-03-08 20:28:32 -05005148bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149 GLuint program,
5150 GLsizei maxcount,
5151 GLsizei *count,
5152 GLuint *shaders)
5153{
5154 if (maxcount < 0)
5155 {
Jamie Madille0472f32018-11-27 16:32:45 -05005156 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005157 return false;
5158 }
5159
5160 Program *programObject = GetValidProgram(context, program);
5161
5162 if (!programObject)
5163 {
5164 return false;
5165 }
5166
5167 return true;
5168}
5169
Jamie Madill5b772312018-03-08 20:28:32 -05005170bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005171{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005172 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5173 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005174 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005175 {
Jamie Madille0472f32018-11-27 16:32:45 -05005176 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005177 return false;
5178 }
5179
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180 Program *programObject = GetValidProgram(context, program);
5181
5182 if (!programObject)
5183 {
Jamie Madille0472f32018-11-27 16:32:45 -05005184 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005185 return false;
5186 }
5187
5188 if (!programObject->isLinked())
5189 {
Jamie Madille0472f32018-11-27 16:32:45 -05005190 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005191 return false;
5192 }
5193
5194 return true;
5195}
5196
Jamie Madill5b772312018-03-08 20:28:32 -05005197bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005198{
5199 GLenum nativeType;
5200 unsigned int numParams = 0;
5201 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5202}
5203
Jamie Madill5b772312018-03-08 20:28:32 -05005204bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005205{
5206 return true;
5207}
5208
Jamie Madill5b772312018-03-08 20:28:32 -05005209bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005210{
5211 GLenum nativeType;
5212 unsigned int numParams = 0;
5213 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5214}
5215
Jamie Madill5b772312018-03-08 20:28:32 -05005216bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005217{
5218 GLenum nativeType;
5219 unsigned int numParams = 0;
5220 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5221}
5222
Jamie Madill5b772312018-03-08 20:28:32 -05005223bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005224 GLuint program,
5225 GLsizei bufsize,
5226 GLsizei *length,
5227 GLchar *infolog)
5228{
5229 if (bufsize < 0)
5230 {
Jamie Madille0472f32018-11-27 16:32:45 -05005231 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005232 return false;
5233 }
5234
5235 Program *programObject = GetValidProgram(context, program);
5236 if (!programObject)
5237 {
5238 return false;
5239 }
5240
5241 return true;
5242}
5243
Jamie Madill5b772312018-03-08 20:28:32 -05005244bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005245 GLuint shader,
5246 GLsizei bufsize,
5247 GLsizei *length,
5248 GLchar *infolog)
5249{
5250 if (bufsize < 0)
5251 {
Jamie Madille0472f32018-11-27 16:32:45 -05005252 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005253 return false;
5254 }
5255
5256 Shader *shaderObject = GetValidShader(context, shader);
5257 if (!shaderObject)
5258 {
5259 return false;
5260 }
5261
5262 return true;
5263}
5264
Jamie Madill5b772312018-03-08 20:28:32 -05005265bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005266 GLenum shadertype,
5267 GLenum precisiontype,
5268 GLint *range,
5269 GLint *precision)
5270{
5271 switch (shadertype)
5272 {
5273 case GL_VERTEX_SHADER:
5274 case GL_FRAGMENT_SHADER:
5275 break;
5276 case GL_COMPUTE_SHADER:
Jamie Madill610640f2018-11-21 17:28:41 -05005277 context->validationError(GL_INVALID_OPERATION,
5278 "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005279 return false;
5280 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005281 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005282 return false;
5283 }
5284
5285 switch (precisiontype)
5286 {
5287 case GL_LOW_FLOAT:
5288 case GL_MEDIUM_FLOAT:
5289 case GL_HIGH_FLOAT:
5290 case GL_LOW_INT:
5291 case GL_MEDIUM_INT:
5292 case GL_HIGH_INT:
5293 break;
5294
5295 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005296 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005297 return false;
5298 }
5299
5300 return true;
5301}
5302
Jamie Madill5b772312018-03-08 20:28:32 -05005303bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005304 GLuint shader,
5305 GLsizei bufsize,
5306 GLsizei *length,
5307 GLchar *source)
5308{
5309 if (bufsize < 0)
5310 {
Jamie Madille0472f32018-11-27 16:32:45 -05005311 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005312 return false;
5313 }
5314
5315 Shader *shaderObject = GetValidShader(context, shader);
5316 if (!shaderObject)
5317 {
5318 return false;
5319 }
5320
5321 return true;
5322}
5323
Jamie Madill5b772312018-03-08 20:28:32 -05005324bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005325{
5326 if (strstr(name, "gl_") == name)
5327 {
5328 return false;
5329 }
5330
Geoff Langfc32e8b2017-05-31 14:16:59 -04005331 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5332 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005333 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005334 {
Jamie Madille0472f32018-11-27 16:32:45 -05005335 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005336 return false;
5337 }
5338
Jamie Madillc1d770e2017-04-13 17:31:24 -04005339 Program *programObject = GetValidProgram(context, program);
5340
5341 if (!programObject)
5342 {
5343 return false;
5344 }
5345
5346 if (!programObject->isLinked())
5347 {
Jamie Madille0472f32018-11-27 16:32:45 -05005348 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349 return false;
5350 }
5351
5352 return true;
5353}
5354
Jamie Madill5b772312018-03-08 20:28:32 -05005355bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356{
5357 switch (mode)
5358 {
5359 case GL_FASTEST:
5360 case GL_NICEST:
5361 case GL_DONT_CARE:
5362 break;
5363
5364 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005365 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005366 return false;
5367 }
5368
5369 switch (target)
5370 {
5371 case GL_GENERATE_MIPMAP_HINT:
5372 break;
5373
Geoff Lange7bd2182017-06-16 16:13:13 -04005374 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5375 if (context->getClientVersion() < ES_3_0 &&
5376 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377 {
Jamie Madill610640f2018-11-21 17:28:41 -05005378 context->validationError(GL_INVALID_ENUM,
5379 "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005380 return false;
5381 }
5382 break;
5383
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005384 case GL_PERSPECTIVE_CORRECTION_HINT:
5385 case GL_POINT_SMOOTH_HINT:
5386 case GL_LINE_SMOOTH_HINT:
5387 case GL_FOG_HINT:
5388 if (context->getClientMajorVersion() >= 2)
5389 {
Jamie Madille0472f32018-11-27 16:32:45 -05005390 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005391 return false;
5392 }
5393 break;
5394
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005396 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397 return false;
5398 }
5399
5400 return true;
5401}
5402
Jamie Madill5b772312018-03-08 20:28:32 -05005403bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404{
5405 return true;
5406}
5407
Jamie Madill5b772312018-03-08 20:28:32 -05005408bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409{
5410 return true;
5411}
5412
Jamie Madill5b772312018-03-08 20:28:32 -05005413bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414{
5415 return true;
5416}
5417
Jamie Madill5b772312018-03-08 20:28:32 -05005418bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419{
5420 return true;
5421}
5422
Jamie Madill5b772312018-03-08 20:28:32 -05005423bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005424{
5425 return true;
5426}
5427
Jamie Madill5b772312018-03-08 20:28:32 -05005428bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005429{
5430 return true;
5431}
5432
Jamie Madill5b772312018-03-08 20:28:32 -05005433bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005434{
5435 if (context->getClientMajorVersion() < 3)
5436 {
5437 switch (pname)
5438 {
5439 case GL_UNPACK_IMAGE_HEIGHT:
5440 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005441 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005442 return false;
5443
5444 case GL_UNPACK_ROW_LENGTH:
5445 case GL_UNPACK_SKIP_ROWS:
5446 case GL_UNPACK_SKIP_PIXELS:
5447 if (!context->getExtensions().unpackSubimage)
5448 {
Jamie Madille0472f32018-11-27 16:32:45 -05005449 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005450 return false;
5451 }
5452 break;
5453
5454 case GL_PACK_ROW_LENGTH:
5455 case GL_PACK_SKIP_ROWS:
5456 case GL_PACK_SKIP_PIXELS:
5457 if (!context->getExtensions().packSubimage)
5458 {
Jamie Madille0472f32018-11-27 16:32:45 -05005459 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005460 return false;
5461 }
5462 break;
5463 }
5464 }
5465
5466 if (param < 0)
5467 {
Jamie Madill610640f2018-11-21 17:28:41 -05005468 context->validationError(GL_INVALID_VALUE, "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469 return false;
5470 }
5471
5472 switch (pname)
5473 {
5474 case GL_UNPACK_ALIGNMENT:
5475 if (param != 1 && param != 2 && param != 4 && param != 8)
5476 {
Jamie Madille0472f32018-11-27 16:32:45 -05005477 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 return false;
5479 }
5480 break;
5481
5482 case GL_PACK_ALIGNMENT:
5483 if (param != 1 && param != 2 && param != 4 && param != 8)
5484 {
Jamie Madille0472f32018-11-27 16:32:45 -05005485 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005486 return false;
5487 }
5488 break;
5489
5490 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005491 if (!context->getExtensions().packReverseRowOrder)
5492 {
Jamie Madille0472f32018-11-27 16:32:45 -05005493 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005494 }
5495 break;
5496
Jamie Madillc1d770e2017-04-13 17:31:24 -04005497 case GL_UNPACK_ROW_LENGTH:
5498 case GL_UNPACK_IMAGE_HEIGHT:
5499 case GL_UNPACK_SKIP_IMAGES:
5500 case GL_UNPACK_SKIP_ROWS:
5501 case GL_UNPACK_SKIP_PIXELS:
5502 case GL_PACK_ROW_LENGTH:
5503 case GL_PACK_SKIP_ROWS:
5504 case GL_PACK_SKIP_PIXELS:
5505 break;
5506
5507 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005508 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509 return false;
5510 }
5511
5512 return true;
5513}
5514
Jamie Madill5b772312018-03-08 20:28:32 -05005515bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005516{
5517 return true;
5518}
5519
Jamie Madill5b772312018-03-08 20:28:32 -05005520bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005521{
5522 return true;
5523}
5524
Jamie Madill5b772312018-03-08 20:28:32 -05005525bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005526{
5527 return true;
5528}
5529
Jamie Madill5b772312018-03-08 20:28:32 -05005530bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531{
5532 if (width < 0 || height < 0)
5533 {
Jamie Madille0472f32018-11-27 16:32:45 -05005534 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535 return false;
5536 }
5537
5538 return true;
5539}
5540
Jamie Madill5b772312018-03-08 20:28:32 -05005541bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005542 GLsizei n,
5543 const GLuint *shaders,
5544 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005545 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005546 GLsizei length)
5547{
5548 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5549 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5550 shaderBinaryFormats.end())
5551 {
Jamie Madill610640f2018-11-21 17:28:41 -05005552 context->validationError(GL_INVALID_ENUM, "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553 return false;
5554 }
5555
5556 return true;
5557}
5558
Jamie Madill5b772312018-03-08 20:28:32 -05005559bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005560 GLuint shader,
5561 GLsizei count,
5562 const GLchar *const *string,
5563 const GLint *length)
5564{
5565 if (count < 0)
5566 {
Jamie Madille0472f32018-11-27 16:32:45 -05005567 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005568 return false;
5569 }
5570
Geoff Langfc32e8b2017-05-31 14:16:59 -04005571 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5572 // shader-related entry points
5573 if (context->getExtensions().webglCompatibility)
5574 {
5575 for (GLsizei i = 0; i < count; i++)
5576 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005577 size_t len =
5578 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005579
5580 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005581 if (!IsValidESSLShaderSourceString(string[i], len,
5582 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005583 {
Jamie Madille0472f32018-11-27 16:32:45 -05005584 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005585 return false;
5586 }
5587 }
5588 }
5589
Jamie Madillc1d770e2017-04-13 17:31:24 -04005590 Shader *shaderObject = GetValidShader(context, shader);
5591 if (!shaderObject)
5592 {
5593 return false;
5594 }
5595
5596 return true;
5597}
5598
Jamie Madill5b772312018-03-08 20:28:32 -05005599bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600{
5601 if (!IsValidStencilFunc(func))
5602 {
Jamie Madille0472f32018-11-27 16:32:45 -05005603 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005604 return false;
5605 }
5606
5607 return true;
5608}
5609
Jamie Madill5b772312018-03-08 20:28:32 -05005610bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611{
5612 if (!IsValidStencilFace(face))
5613 {
Jamie Madille0472f32018-11-27 16:32:45 -05005614 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005615 return false;
5616 }
5617
5618 if (!IsValidStencilFunc(func))
5619 {
Jamie Madille0472f32018-11-27 16:32:45 -05005620 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005621 return false;
5622 }
5623
5624 return true;
5625}
5626
Jamie Madill5b772312018-03-08 20:28:32 -05005627bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628{
5629 return true;
5630}
5631
Jamie Madill5b772312018-03-08 20:28:32 -05005632bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005633{
5634 if (!IsValidStencilFace(face))
5635 {
Jamie Madille0472f32018-11-27 16:32:45 -05005636 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005637 return false;
5638 }
5639
5640 return true;
5641}
5642
Jamie Madill5b772312018-03-08 20:28:32 -05005643bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005644{
5645 if (!IsValidStencilOp(fail))
5646 {
Jamie Madille0472f32018-11-27 16:32:45 -05005647 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648 return false;
5649 }
5650
5651 if (!IsValidStencilOp(zfail))
5652 {
Jamie Madille0472f32018-11-27 16:32:45 -05005653 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005654 return false;
5655 }
5656
5657 if (!IsValidStencilOp(zpass))
5658 {
Jamie Madille0472f32018-11-27 16:32:45 -05005659 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660 return false;
5661 }
5662
5663 return true;
5664}
5665
Jamie Madill5b772312018-03-08 20:28:32 -05005666bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005667 GLenum face,
5668 GLenum fail,
5669 GLenum zfail,
5670 GLenum zpass)
5671{
5672 if (!IsValidStencilFace(face))
5673 {
Jamie Madille0472f32018-11-27 16:32:45 -05005674 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675 return false;
5676 }
5677
5678 return ValidateStencilOp(context, fail, zfail, zpass);
5679}
5680
Jamie Madill5b772312018-03-08 20:28:32 -05005681bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005682{
5683 return ValidateUniform(context, GL_FLOAT, location, 1);
5684}
5685
Jamie Madill5b772312018-03-08 20:28:32 -05005686bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687{
5688 return ValidateUniform(context, GL_FLOAT, location, count);
5689}
5690
Jamie Madill5b772312018-03-08 20:28:32 -05005691bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005692{
5693 return ValidateUniform1iv(context, location, 1, &x);
5694}
5695
Jamie Madill5b772312018-03-08 20:28:32 -05005696bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005697{
5698 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5699}
5700
Jamie Madill5b772312018-03-08 20:28:32 -05005701bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005702{
5703 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5704}
5705
Jamie Madill5b772312018-03-08 20:28:32 -05005706bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005707{
5708 return ValidateUniform(context, GL_INT_VEC2, location, count);
5709}
5710
Jamie Madill5b772312018-03-08 20:28:32 -05005711bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005712{
5713 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5714}
5715
Jamie Madill5b772312018-03-08 20:28:32 -05005716bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005717{
5718 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5719}
5720
Jamie Madill5b772312018-03-08 20:28:32 -05005721bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005722{
5723 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5724}
5725
Jamie Madill5b772312018-03-08 20:28:32 -05005726bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005727{
5728 return ValidateUniform(context, GL_INT_VEC3, location, count);
5729}
5730
Jamie Madill5b772312018-03-08 20:28:32 -05005731bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005732{
5733 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5734}
5735
Jamie Madill5b772312018-03-08 20:28:32 -05005736bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005737{
5738 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5739}
5740
Jamie Madill5b772312018-03-08 20:28:32 -05005741bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742{
5743 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5744}
5745
Jamie Madill5b772312018-03-08 20:28:32 -05005746bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005747{
5748 return ValidateUniform(context, GL_INT_VEC4, location, count);
5749}
5750
Jamie Madill5b772312018-03-08 20:28:32 -05005751bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005752 GLint location,
5753 GLsizei count,
5754 GLboolean transpose,
5755 const GLfloat *value)
5756{
5757 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5758}
5759
Jamie Madill5b772312018-03-08 20:28:32 -05005760bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005761 GLint location,
5762 GLsizei count,
5763 GLboolean transpose,
5764 const GLfloat *value)
5765{
5766 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5767}
5768
Jamie Madill5b772312018-03-08 20:28:32 -05005769bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005770 GLint location,
5771 GLsizei count,
5772 GLboolean transpose,
5773 const GLfloat *value)
5774{
5775 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 Program *programObject = GetValidProgram(context, program);
5781
5782 if (!programObject)
5783 {
5784 return false;
5785 }
5786
5787 return true;
5788}
5789
Jamie Madill5b772312018-03-08 20:28:32 -05005790bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005791{
5792 return ValidateVertexAttribIndex(context, index);
5793}
5794
Jamie Madill5b772312018-03-08 20:28:32 -05005795bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005796{
5797 return ValidateVertexAttribIndex(context, index);
5798}
5799
Jamie Madill5b772312018-03-08 20:28:32 -05005800bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005801{
5802 return ValidateVertexAttribIndex(context, index);
5803}
5804
Jamie Madill5b772312018-03-08 20:28:32 -05005805bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005806{
5807 return ValidateVertexAttribIndex(context, index);
5808}
5809
Jamie Madill5b772312018-03-08 20:28:32 -05005810bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005811{
5812 return ValidateVertexAttribIndex(context, index);
5813}
5814
Jamie Madill5b772312018-03-08 20:28:32 -05005815bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005816{
5817 return ValidateVertexAttribIndex(context, index);
5818}
5819
Jamie Madill5b772312018-03-08 20:28:32 -05005820bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821 GLuint index,
5822 GLfloat x,
5823 GLfloat y,
5824 GLfloat z,
5825 GLfloat w)
5826{
5827 return ValidateVertexAttribIndex(context, index);
5828}
5829
Jamie Madill5b772312018-03-08 20:28:32 -05005830bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005831{
5832 return ValidateVertexAttribIndex(context, index);
5833}
5834
Jamie Madill5b772312018-03-08 20:28:32 -05005835bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005836{
5837 if (width < 0 || height < 0)
5838 {
Jamie Madille0472f32018-11-27 16:32:45 -05005839 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005840 return false;
5841 }
5842
5843 return true;
5844}
5845
Jamie Madill5b772312018-03-08 20:28:32 -05005846bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005847 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005848 GLsizei count,
5849 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005850 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005851{
5852 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5853}
5854
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005855bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005856 GLenum target,
5857 GLenum attachment,
5858 GLenum pname,
5859 GLint *params)
5860{
5861 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5862 nullptr);
5863}
5864
Jamie Madill5b772312018-03-08 20:28:32 -05005865bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005866{
5867 return ValidateGetProgramivBase(context, program, pname, nullptr);
5868}
5869
Jamie Madill5b772312018-03-08 20:28:32 -05005870bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005871 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005872 GLint level,
5873 GLenum internalformat,
5874 GLint x,
5875 GLint y,
5876 GLsizei width,
5877 GLsizei height,
5878 GLint border)
5879{
5880 if (context->getClientMajorVersion() < 3)
5881 {
5882 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5883 0, x, y, width, height, border);
5884 }
5885
5886 ASSERT(context->getClientMajorVersion() == 3);
5887 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5888 0, x, y, width, height, border);
5889}
5890
5891bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005892 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005893 GLint level,
5894 GLint xoffset,
5895 GLint yoffset,
5896 GLint x,
5897 GLint y,
5898 GLsizei width,
5899 GLsizei height)
5900{
5901 if (context->getClientMajorVersion() < 3)
5902 {
5903 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5904 yoffset, x, y, width, height, 0);
5905 }
5906
5907 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5908 yoffset, 0, x, y, width, height, 0);
5909}
5910
5911bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5912{
5913 return ValidateGenOrDelete(context, n);
5914}
5915
5916bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5917{
5918 return ValidateGenOrDelete(context, n);
5919}
5920
5921bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5922{
5923 return ValidateGenOrDelete(context, n);
5924}
5925
5926bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5927{
5928 return ValidateGenOrDelete(context, n);
5929}
5930
5931bool ValidateDisable(Context *context, GLenum cap)
5932{
5933 if (!ValidCap(context, cap, false))
5934 {
Jamie Madille0472f32018-11-27 16:32:45 -05005935 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005936 return false;
5937 }
5938
5939 return true;
5940}
5941
5942bool ValidateEnable(Context *context, GLenum cap)
5943{
5944 if (!ValidCap(context, cap, false))
5945 {
Jamie Madille0472f32018-11-27 16:32:45 -05005946 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005947 return false;
5948 }
5949
5950 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5951 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5952 {
5953 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Jamie Madill610640f2018-11-21 17:28:41 -05005954 context->validationError(GL_INVALID_OPERATION, errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005955
5956 // We also output an error message to the debugger window if tracing is active, so that
5957 // developers can see the error message.
5958 ERR() << errorMessage;
5959 return false;
5960 }
5961
5962 return true;
5963}
5964
5965bool ValidateFramebufferRenderbuffer(Context *context,
5966 GLenum target,
5967 GLenum attachment,
5968 GLenum renderbuffertarget,
5969 GLuint renderbuffer)
5970{
Geoff Lange8afa902017-09-27 15:00:43 -04005971 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005972 {
Jamie Madille0472f32018-11-27 16:32:45 -05005973 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07005974 return false;
5975 }
5976
5977 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5978 {
Jamie Madille0472f32018-11-27 16:32:45 -05005979 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005980 return false;
5981 }
5982
5983 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5984 renderbuffertarget, renderbuffer);
5985}
5986
5987bool ValidateFramebufferTexture2D(Context *context,
5988 GLenum target,
5989 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005990 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005991 GLuint texture,
5992 GLint level)
5993{
5994 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5995 // extension
5996 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5997 level != 0)
5998 {
Jamie Madille0472f32018-11-27 16:32:45 -05005999 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006000 return false;
6001 }
6002
6003 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6004 {
6005 return false;
6006 }
6007
6008 if (texture != 0)
6009 {
6010 gl::Texture *tex = context->getTexture(texture);
6011 ASSERT(tex);
6012
6013 const gl::Caps &caps = context->getCaps();
6014
6015 switch (textarget)
6016 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006017 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006018 {
6019 if (level > gl::log2(caps.max2DTextureSize))
6020 {
Jamie Madille0472f32018-11-27 16:32:45 -05006021 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006022 return false;
6023 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006024 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 {
Jamie Madille0472f32018-11-27 16:32:45 -05006026 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 return false;
6028 }
6029 }
6030 break;
6031
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006032 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006033 {
6034 if (level != 0)
6035 {
Jamie Madille0472f32018-11-27 16:32:45 -05006036 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006037 return false;
6038 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006039 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006040 {
Jamie Madill610640f2018-11-21 17:28:41 -05006041 context->validationError(GL_INVALID_OPERATION,
6042 "Textarget must match the texture target type.");
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006043 return false;
6044 }
6045 }
6046 break;
6047
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006048 case TextureTarget::CubeMapNegativeX:
6049 case TextureTarget::CubeMapNegativeY:
6050 case TextureTarget::CubeMapNegativeZ:
6051 case TextureTarget::CubeMapPositiveX:
6052 case TextureTarget::CubeMapPositiveY:
6053 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006054 {
6055 if (level > gl::log2(caps.maxCubeMapTextureSize))
6056 {
Jamie Madille0472f32018-11-27 16:32:45 -05006057 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return false;
6059 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006060 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006061 {
Jamie Madill610640f2018-11-21 17:28:41 -05006062 context->validationError(GL_INVALID_OPERATION,
6063 "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006064 return false;
6065 }
6066 }
6067 break;
6068
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006069 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006071 if (context->getClientVersion() < ES_3_1 &&
6072 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 {
Jamie Madill610640f2018-11-21 17:28:41 -05006074 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006075 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 return false;
6077 }
6078
6079 if (level != 0)
6080 {
Jamie Madille0472f32018-11-27 16:32:45 -05006081 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006082 return false;
6083 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006084 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006085 {
Jamie Madill610640f2018-11-21 17:28:41 -05006086 context->validationError(GL_INVALID_OPERATION,
6087 "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 return false;
6089 }
6090 }
6091 break;
6092
6093 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006094 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006095 return false;
6096 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006097 }
6098
6099 return true;
6100}
6101
6102bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6103{
6104 return ValidateGenOrDelete(context, n);
6105}
6106
6107bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6108{
6109 return ValidateGenOrDelete(context, n);
6110}
6111
6112bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6113{
6114 return ValidateGenOrDelete(context, n);
6115}
6116
6117bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6118{
6119 return ValidateGenOrDelete(context, n);
6120}
6121
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006122bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006123{
6124 if (!ValidTextureTarget(context, target))
6125 {
Jamie Madille0472f32018-11-27 16:32:45 -05006126 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
6129
6130 Texture *texture = context->getTargetTexture(target);
6131
6132 if (texture == nullptr)
6133 {
Jamie Madille0472f32018-11-27 16:32:45 -05006134 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006135 return false;
6136 }
6137
6138 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6139
6140 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6141 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6142 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6143 {
Jamie Madille0472f32018-11-27 16:32:45 -05006144 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006145 return false;
6146 }
6147
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006148 TextureTarget baseTarget = (target == TextureType::CubeMap)
6149 ? TextureTarget::CubeMapPositiveX
6150 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006151 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6152 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6153 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006154 {
Jamie Madille0472f32018-11-27 16:32:45 -05006155 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006156 return false;
6157 }
6158
Geoff Lang536eca12017-09-13 11:23:35 -04006159 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6160 bool formatUnsized = !format.sized;
6161 bool formatColorRenderableAndFilterable =
6162 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006163 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006164 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006165 {
Jamie Madille0472f32018-11-27 16:32:45 -05006166 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006167 return false;
6168 }
6169
Geoff Lang536eca12017-09-13 11:23:35 -04006170 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6171 // generation
6172 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6173 {
Jamie Madille0472f32018-11-27 16:32:45 -05006174 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006175 return false;
6176 }
6177
Jiange2c00842018-07-13 16:50:49 +08006178 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6179 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6180 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006181 {
Jamie Madille0472f32018-11-27 16:32:45 -05006182 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006183 return false;
6184 }
6185
6186 // Non-power of 2 ES2 check
6187 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6188 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6189 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6190 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006191 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6192 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006193 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006194 return false;
6195 }
6196
6197 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006198 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006199 {
Jamie Madille0472f32018-11-27 16:32:45 -05006200 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006201 return false;
6202 }
6203
6204 return true;
6205}
6206
Jamie Madill5b772312018-03-08 20:28:32 -05006207bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006208 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006209 GLenum pname,
6210 GLint *params)
6211{
6212 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6213}
6214
6215bool ValidateGetRenderbufferParameteriv(Context *context,
6216 GLenum target,
6217 GLenum pname,
6218 GLint *params)
6219{
6220 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6221}
6222
6223bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6224{
6225 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6226}
6227
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006228bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006229{
6230 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6231}
6232
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006233bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006234{
6235 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6236}
6237
Till Rathmannb8543632018-10-02 19:46:14 +02006238bool ValidateGetTexParameterIivOES(Context *context,
6239 TextureType target,
6240 GLenum pname,
6241 GLint *params)
6242{
6243 if (context->getClientMajorVersion() < 3)
6244 {
Jamie Madille0472f32018-11-27 16:32:45 -05006245 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006246 return false;
6247 }
6248 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6249}
6250
6251bool ValidateGetTexParameterIuivOES(Context *context,
6252 TextureType target,
6253 GLenum pname,
6254 GLuint *params)
6255{
6256 if (context->getClientMajorVersion() < 3)
6257 {
Jamie Madille0472f32018-11-27 16:32:45 -05006258 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006259 return false;
6260 }
6261 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6262}
6263
Jamie Madillbe849e42017-05-02 15:49:00 -04006264bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6265{
6266 return ValidateGetUniformBase(context, program, location);
6267}
6268
6269bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6270{
6271 return ValidateGetUniformBase(context, program, location);
6272}
6273
6274bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6275{
6276 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6277}
6278
6279bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6280{
6281 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6282}
6283
6284bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6285{
6286 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6287}
6288
6289bool ValidateIsEnabled(Context *context, GLenum cap)
6290{
6291 if (!ValidCap(context, cap, true))
6292 {
Jamie Madille0472f32018-11-27 16:32:45 -05006293 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006294 return false;
6295 }
6296
6297 return true;
6298}
6299
6300bool ValidateLinkProgram(Context *context, GLuint program)
6301{
6302 if (context->hasActiveTransformFeedback(program))
6303 {
6304 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05006305 context->validationError(GL_INVALID_OPERATION,
6306 "Cannot link program while program is "
6307 "associated with an active transform "
6308 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006309 return false;
6310 }
6311
6312 Program *programObject = GetValidProgram(context, program);
6313 if (!programObject)
6314 {
6315 return false;
6316 }
6317
6318 return true;
6319}
6320
Jamie Madill4928b7c2017-06-20 12:57:39 -04006321bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006322 GLint x,
6323 GLint y,
6324 GLsizei width,
6325 GLsizei height,
6326 GLenum format,
6327 GLenum type,
6328 void *pixels)
6329{
6330 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6331 nullptr, pixels);
6332}
6333
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006334bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006335{
Till Rathmannb8543632018-10-02 19:46:14 +02006336 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006337}
6338
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006339bool ValidateTexParameterfv(Context *context,
6340 TextureType target,
6341 GLenum pname,
6342 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006343{
Till Rathmannb8543632018-10-02 19:46:14 +02006344 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006345}
6346
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006347bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006348{
Till Rathmannb8543632018-10-02 19:46:14 +02006349 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006350}
6351
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006352bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006353{
Till Rathmannb8543632018-10-02 19:46:14 +02006354 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6355}
6356
6357bool ValidateTexParameterIivOES(Context *context,
6358 TextureType target,
6359 GLenum pname,
6360 const GLint *params)
6361{
6362 if (context->getClientMajorVersion() < 3)
6363 {
Jamie Madille0472f32018-11-27 16:32:45 -05006364 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006365 return false;
6366 }
6367 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6368}
6369
6370bool ValidateTexParameterIuivOES(Context *context,
6371 TextureType target,
6372 GLenum pname,
6373 const GLuint *params)
6374{
6375 if (context->getClientMajorVersion() < 3)
6376 {
Jamie Madille0472f32018-11-27 16:32:45 -05006377 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006378 return false;
6379 }
6380 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006381}
6382
6383bool ValidateUseProgram(Context *context, GLuint program)
6384{
6385 if (program != 0)
6386 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006387 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006388 if (!programObject)
6389 {
6390 // ES 3.1.0 section 7.3 page 72
6391 if (context->getShader(program))
6392 {
Jamie Madille0472f32018-11-27 16:32:45 -05006393 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006394 return false;
6395 }
6396 else
6397 {
Jamie Madille0472f32018-11-27 16:32:45 -05006398 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006399 return false;
6400 }
6401 }
6402 if (!programObject->isLinked())
6403 {
Jamie Madille0472f32018-11-27 16:32:45 -05006404 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006405 return false;
6406 }
6407 }
6408 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6409 {
6410 // ES 3.0.4 section 2.15 page 91
Jamie Madill610640f2018-11-21 17:28:41 -05006411 context->validationError(
6412 GL_INVALID_OPERATION,
6413 "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006414 return false;
6415 }
6416
6417 return true;
6418}
6419
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006420bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6421{
6422 if (!context->getExtensions().fence)
6423 {
Jamie Madille0472f32018-11-27 16:32:45 -05006424 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006425 return false;
6426 }
6427
6428 if (n < 0)
6429 {
Jamie Madille0472f32018-11-27 16:32:45 -05006430 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006431 return false;
6432 }
6433
6434 return true;
6435}
6436
6437bool ValidateFinishFenceNV(Context *context, GLuint fence)
6438{
6439 if (!context->getExtensions().fence)
6440 {
Jamie Madille0472f32018-11-27 16:32:45 -05006441 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006442 return false;
6443 }
6444
6445 FenceNV *fenceObject = context->getFenceNV(fence);
6446
6447 if (fenceObject == nullptr)
6448 {
Jamie Madille0472f32018-11-27 16:32:45 -05006449 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006450 return false;
6451 }
6452
6453 if (!fenceObject->isSet())
6454 {
Jamie Madille0472f32018-11-27 16:32:45 -05006455 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006456 return false;
6457 }
6458
6459 return true;
6460}
6461
6462bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6463{
6464 if (!context->getExtensions().fence)
6465 {
Jamie Madille0472f32018-11-27 16:32:45 -05006466 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006467 return false;
6468 }
6469
6470 if (n < 0)
6471 {
Jamie Madille0472f32018-11-27 16:32:45 -05006472 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006473 return false;
6474 }
6475
6476 return true;
6477}
6478
6479bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6480{
6481 if (!context->getExtensions().fence)
6482 {
Jamie Madille0472f32018-11-27 16:32:45 -05006483 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006484 return false;
6485 }
6486
6487 FenceNV *fenceObject = context->getFenceNV(fence);
6488
6489 if (fenceObject == nullptr)
6490 {
Jamie Madille0472f32018-11-27 16:32:45 -05006491 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006492 return false;
6493 }
6494
6495 if (!fenceObject->isSet())
6496 {
Jamie Madille0472f32018-11-27 16:32:45 -05006497 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006498 return false;
6499 }
6500
6501 switch (pname)
6502 {
6503 case GL_FENCE_STATUS_NV:
6504 case GL_FENCE_CONDITION_NV:
6505 break;
6506
6507 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006508 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006509 return false;
6510 }
6511
6512 return true;
6513}
6514
6515bool ValidateGetGraphicsResetStatusEXT(Context *context)
6516{
6517 if (!context->getExtensions().robustness)
6518 {
Jamie Madille0472f32018-11-27 16:32:45 -05006519 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006520 return false;
6521 }
6522
6523 return true;
6524}
6525
6526bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6527 GLuint shader,
6528 GLsizei bufsize,
6529 GLsizei *length,
6530 GLchar *source)
6531{
6532 if (!context->getExtensions().translatedShaderSource)
6533 {
Jamie Madille0472f32018-11-27 16:32:45 -05006534 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006535 return false;
6536 }
6537
6538 if (bufsize < 0)
6539 {
Jamie Madille0472f32018-11-27 16:32:45 -05006540 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006541 return false;
6542 }
6543
6544 Shader *shaderObject = context->getShader(shader);
6545
6546 if (!shaderObject)
6547 {
Jamie Madille0472f32018-11-27 16:32:45 -05006548 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006549 return false;
6550 }
6551
6552 return true;
6553}
6554
6555bool ValidateIsFenceNV(Context *context, GLuint fence)
6556{
6557 if (!context->getExtensions().fence)
6558 {
Jamie Madille0472f32018-11-27 16:32:45 -05006559 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006560 return false;
6561 }
6562
6563 return true;
6564}
6565
Jamie Madill007530e2017-12-28 14:27:04 -05006566bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6567{
6568 if (!context->getExtensions().fence)
6569 {
Jamie Madille0472f32018-11-27 16:32:45 -05006570 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006571 return false;
6572 }
6573
6574 if (condition != GL_ALL_COMPLETED_NV)
6575 {
Jamie Madille0472f32018-11-27 16:32:45 -05006576 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006577 return false;
6578 }
6579
6580 FenceNV *fenceObject = context->getFenceNV(fence);
6581
6582 if (fenceObject == nullptr)
6583 {
Jamie Madille0472f32018-11-27 16:32:45 -05006584 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006585 return false;
6586 }
6587
6588 return true;
6589}
6590
6591bool ValidateTestFenceNV(Context *context, GLuint fence)
6592{
6593 if (!context->getExtensions().fence)
6594 {
Jamie Madille0472f32018-11-27 16:32:45 -05006595 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006596 return false;
6597 }
6598
6599 FenceNV *fenceObject = context->getFenceNV(fence);
6600
6601 if (fenceObject == nullptr)
6602 {
Jamie Madille0472f32018-11-27 16:32:45 -05006603 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006604 return false;
6605 }
6606
6607 if (fenceObject->isSet() != GL_TRUE)
6608 {
Jamie Madille0472f32018-11-27 16:32:45 -05006609 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006610 return false;
6611 }
6612
6613 return true;
6614}
6615
6616bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006617 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006618 GLsizei levels,
6619 GLenum internalformat,
6620 GLsizei width,
6621 GLsizei height)
6622{
6623 if (!context->getExtensions().textureStorage)
6624 {
Jamie Madille0472f32018-11-27 16:32:45 -05006625 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006626 return false;
6627 }
6628
6629 if (context->getClientMajorVersion() < 3)
6630 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006631 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006632 height);
6633 }
6634
6635 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006636 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006637 1);
6638}
6639
6640bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6641{
6642 if (!context->getExtensions().instancedArrays)
6643 {
Jamie Madille0472f32018-11-27 16:32:45 -05006644 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006645 return false;
6646 }
6647
6648 if (index >= MAX_VERTEX_ATTRIBS)
6649 {
Jamie Madille0472f32018-11-27 16:32:45 -05006650 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006651 return false;
6652 }
6653
6654 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6655 {
6656 if (index == 0 && divisor != 0)
6657 {
6658 const char *errorMessage =
6659 "The current context doesn't support setting a non-zero divisor on the "
6660 "attribute with index zero. "
6661 "Please reorder the attributes in your vertex shader so that attribute zero "
6662 "can have a zero divisor.";
Jamie Madill610640f2018-11-21 17:28:41 -05006663 context->validationError(GL_INVALID_OPERATION, errorMessage);
Jamie Madill007530e2017-12-28 14:27:04 -05006664
6665 // We also output an error message to the debugger window if tracing is active, so
6666 // that developers can see the error message.
6667 ERR() << errorMessage;
6668 return false;
6669 }
6670 }
6671
6672 return true;
6673}
6674
6675bool ValidateTexImage3DOES(Context *context,
6676 GLenum target,
6677 GLint level,
6678 GLenum internalformat,
6679 GLsizei width,
6680 GLsizei height,
6681 GLsizei depth,
6682 GLint border,
6683 GLenum format,
6684 GLenum type,
6685 const void *pixels)
6686{
6687 UNIMPLEMENTED(); // FIXME
6688 return false;
6689}
6690
6691bool ValidatePopGroupMarkerEXT(Context *context)
6692{
6693 if (!context->getExtensions().debugMarker)
6694 {
6695 // The debug marker calls should not set error state
6696 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006697 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006698 return false;
6699 }
6700
6701 return true;
6702}
6703
Jamie Madillfa920eb2018-01-04 11:45:50 -05006704bool ValidateTexStorage1DEXT(Context *context,
6705 GLenum target,
6706 GLsizei levels,
6707 GLenum internalformat,
6708 GLsizei width)
6709{
6710 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006711 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006712 return false;
6713}
6714
6715bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006716 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006717 GLsizei levels,
6718 GLenum internalformat,
6719 GLsizei width,
6720 GLsizei height,
6721 GLsizei depth)
6722{
6723 if (!context->getExtensions().textureStorage)
6724 {
Jamie Madille0472f32018-11-27 16:32:45 -05006725 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006726 return false;
6727 }
6728
6729 if (context->getClientMajorVersion() < 3)
6730 {
Jamie Madille0472f32018-11-27 16:32:45 -05006731 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006732 return false;
6733 }
6734
6735 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6736 depth);
6737}
6738
jchen1082af6202018-06-22 10:59:52 +08006739bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6740{
6741 if (!context->getExtensions().parallelShaderCompile)
6742 {
Jamie Madille0472f32018-11-27 16:32:45 -05006743 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006744 return false;
6745 }
6746 return true;
6747}
6748
Austin Eng1bf18ce2018-10-19 15:34:02 -07006749bool ValidateMultiDrawArraysANGLE(Context *context,
6750 PrimitiveMode mode,
6751 const GLint *firsts,
6752 const GLsizei *counts,
6753 GLsizei drawcount)
6754{
6755 if (!context->getExtensions().multiDraw)
6756 {
Jamie Madille0472f32018-11-27 16:32:45 -05006757 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006758 return false;
6759 }
6760 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6761 {
6762 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6763 {
6764 return false;
6765 }
6766 }
6767 return true;
6768}
6769
6770bool ValidateMultiDrawElementsANGLE(Context *context,
6771 PrimitiveMode mode,
6772 const GLsizei *counts,
6773 GLenum type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006774 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006775 GLsizei drawcount)
6776{
6777 if (!context->getExtensions().multiDraw)
6778 {
Jamie Madille0472f32018-11-27 16:32:45 -05006779 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006780 return false;
6781 }
6782 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6783 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006784 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006785 {
6786 return false;
6787 }
6788 }
6789 return true;
6790}
6791
Jamie Madillc29968b2016-01-20 11:17:23 -05006792} // namespace gl