blob: da61ed44be87d28682e90b0d946f08c2debd9e0c [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 Madillc3dc5d42018-12-30 12:12:04 -050059 if (context->getState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050060 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -050061 const Rectangle &scissor = context->getState().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 Madillc3e37312018-11-30 15:25:39 -050099 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänend59ca052016-06-21 16:10:00 +0300100 return false;
101 }
102
103 if (paths == nullptr)
104 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500105 context->validationError(GL_INVALID_VALUE, kInvalidPathNameArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300106 return false;
107 }
108
109 if (numPaths < 0)
110 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500111 context->validationError(GL_INVALID_VALUE, kInvalidPathNumPaths);
Sami Väisänend59ca052016-06-21 16:10:00 +0300112 return false;
113 }
114
115 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
116 {
Jamie Madille0472f32018-11-27 16:32:45 -0500117 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300118 return false;
119 }
120
121 std::uint32_t pathNameTypeSize = 0;
122 std::uint32_t componentCount = 0;
123
124 switch (pathNameType)
125 {
126 case GL_UNSIGNED_BYTE:
127 pathNameTypeSize = sizeof(GLubyte);
128 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
129 return false;
130 break;
131
132 case GL_BYTE:
133 pathNameTypeSize = sizeof(GLbyte);
134 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
135 return false;
136 break;
137
138 case GL_UNSIGNED_SHORT:
139 pathNameTypeSize = sizeof(GLushort);
140 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
141 return false;
142 break;
143
144 case GL_SHORT:
145 pathNameTypeSize = sizeof(GLshort);
146 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
147 return false;
148 break;
149
150 case GL_UNSIGNED_INT:
151 pathNameTypeSize = sizeof(GLuint);
152 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
153 return false;
154 break;
155
156 case GL_INT:
157 pathNameTypeSize = sizeof(GLint);
158 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
159 return false;
160 break;
161
162 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500163 context->validationError(GL_INVALID_ENUM, kInvalidPathNameType);
Sami Väisänend59ca052016-06-21 16:10:00 +0300164 return false;
165 }
166
167 switch (transformType)
168 {
169 case GL_NONE:
170 componentCount = 0;
171 break;
172 case GL_TRANSLATE_X_CHROMIUM:
173 case GL_TRANSLATE_Y_CHROMIUM:
174 componentCount = 1;
175 break;
176 case GL_TRANSLATE_2D_CHROMIUM:
177 componentCount = 2;
178 break;
179 case GL_TRANSLATE_3D_CHROMIUM:
180 componentCount = 3;
181 break;
182 case GL_AFFINE_2D_CHROMIUM:
183 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
184 componentCount = 6;
185 break;
186 case GL_AFFINE_3D_CHROMIUM:
187 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
188 componentCount = 12;
189 break;
190 default:
Jamie Madillc3e37312018-11-30 15:25:39 -0500191 context->validationError(GL_INVALID_ENUM, kInvalidTransformation);
Sami Väisänend59ca052016-06-21 16:10:00 +0300192 return false;
193 }
194 if (componentCount != 0 && transformValues == nullptr)
195 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500196 context->validationError(GL_INVALID_VALUE, kNoTransformArray);
Sami Väisänend59ca052016-06-21 16:10:00 +0300197 return false;
198 }
199
200 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
201 checkedSize += (numPaths * pathNameTypeSize);
202 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
203 if (!checkedSize.IsValid())
204 {
Jamie Madille0472f32018-11-27 16:32:45 -0500205 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300206 return false;
207 }
208
209 return true;
210}
211
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700213{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400215 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700216 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400217 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700218 case GL_ALPHA:
219 case GL_LUMINANCE:
220 case GL_LUMINANCE_ALPHA:
221 case GL_RGB:
222 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400223 case GL_RGB8:
224 case GL_RGBA8:
225 case GL_BGRA_EXT:
226 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700227 return true;
228
Geoff Lang4f0e0032017-05-01 16:04:35 -0400229 default:
230 return false;
231 }
232}
Geoff Lang97073d12016-04-20 10:42:34 -0700233
Geoff Lang4f0e0032017-05-01 16:04:35 -0400234bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
235{
236 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
237}
238
Geoff Lang4f0e0032017-05-01 16:04:35 -0400239bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
240{
241 // Table 1.0 from the CHROMIUM_copy_texture spec
242 switch (internalFormat)
243 {
244 case GL_RGB:
245 case GL_RGBA:
246 case GL_RGB8:
247 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700248 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400249 case GL_BGRA8_EXT:
250 case GL_SRGB_EXT:
251 case GL_SRGB_ALPHA_EXT:
252 case GL_R8:
253 case GL_R8UI:
254 case GL_RG8:
255 case GL_RG8UI:
256 case GL_SRGB8:
257 case GL_RGB565:
258 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400259 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400260 case GL_SRGB8_ALPHA8:
261 case GL_RGB5_A1:
262 case GL_RGBA4:
263 case GL_RGBA8UI:
264 case GL_RGB9_E5:
265 case GL_R16F:
266 case GL_R32F:
267 case GL_RG16F:
268 case GL_RG32F:
269 case GL_RGB16F:
270 case GL_RGB32F:
271 case GL_RGBA16F:
272 case GL_RGBA32F:
273 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700274 case GL_LUMINANCE:
275 case GL_LUMINANCE_ALPHA:
276 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400277 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700278
279 default:
280 return false;
281 }
282}
283
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400284bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
285{
286 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
287}
288
Geoff Lang97073d12016-04-20 10:42:34 -0700289bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
290{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700292 {
Jamie Madille0472f32018-11-27 16:32:45 -0500293 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400294 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700295 }
296
Geoff Langc0094ec2017-08-16 14:16:24 -0400297 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
298 {
Jamie Madille0472f32018-11-27 16:32:45 -0500299 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400300 return false;
301 }
302
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
304 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700305 {
Jamie Madille0472f32018-11-27 16:32:45 -0500306 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400307 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700308 }
309
310 return true;
311}
312
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800313bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700314{
315 switch (target)
316 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800317 case TextureTarget::_2D:
318 case TextureTarget::CubeMapNegativeX:
319 case TextureTarget::CubeMapNegativeY:
320 case TextureTarget::CubeMapNegativeZ:
321 case TextureTarget::CubeMapPositiveX:
322 case TextureTarget::CubeMapPositiveY:
323 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800326 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400327 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700328
329 default:
330 return false;
331 }
332}
333
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800334bool IsValidCopyTextureDestinationTarget(Context *context,
335 TextureType textureType,
336 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400337{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400339}
340
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700344 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800347 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400348 return context->getExtensions().textureRectangle;
Geoff Langbe607ad2018-11-29 10:14:22 -0500349 case TextureType::External:
350 return context->getExtensions().eglImageExternal;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Jamie Madille0472f32018-11-27 16:32:45 -0500474 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500481 // Error is already handled.
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
Jamie Madillc3dc5d42018-12-30 12:12:04 -0500493 const gl::Framebuffer *framebuffer = context->getState().getReadFramebuffer();
Jamie Madillbe849e42017-05-02 15:49:00 -0400494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Jamie Madille0472f32018-11-27 16:32:45 -0500508 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Jamie Madille0472f32018-11-27 16:32:45 -0500519 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Jamie Madille0472f32018-11-27 16:32:45 -0500532 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Jamie Madille0472f32018-11-27 16:32:45 -0500544 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Jamie Madille0472f32018-11-27 16:32:45 -0500555 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Jamie Madille0472f32018-11-27 16:32:45 -0500565 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Olli Etuahof2ed2992018-10-04 13:54:42 +0300579 case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
580 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
581 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
582 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
Jamie Madille0472f32018-11-27 16:32:45 -0500583 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 case GL_DEPTH_COMPONENT:
586 case GL_DEPTH_STENCIL_OES:
Jamie Madille0472f32018-11-27 16:32:45 -0500587 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400588 return false;
589 default:
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 }
593
594 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
595 {
Jamie Madille0472f32018-11-27 16:32:45 -0500596 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 }
600 else
601 {
602 switch (internalformat)
603 {
604 case GL_ALPHA:
605 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
606 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
607 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Jamie Madille0472f32018-11-27 16:32:45 -0500609 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_LUMINANCE:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Jamie Madille0472f32018-11-27 16:32:45 -0500620 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RED_EXT:
625 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
626 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
627 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
628 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
629 colorbufferFormat != GL_BGR5_A1_ANGLEX)
630 {
Jamie Madille0472f32018-11-27 16:32:45 -0500631 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400632 return false;
633 }
634 break;
635 case GL_RG_EXT:
636 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
637 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
638 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
639 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
640 {
Jamie Madille0472f32018-11-27 16:32:45 -0500641 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400642 return false;
643 }
644 break;
645 case GL_RGB:
646 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
647 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
648 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
649 colorbufferFormat != GL_BGR5_A1_ANGLEX)
650 {
Jamie Madille0472f32018-11-27 16:32:45 -0500651 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400652 return false;
653 }
654 break;
655 case GL_LUMINANCE_ALPHA:
656 case GL_RGBA:
657 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
658 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
659 colorbufferFormat != GL_BGR5_A1_ANGLEX)
660 {
Jamie Madille0472f32018-11-27 16:32:45 -0500661 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
666 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
667 if (context->getExtensions().textureCompressionDXT1)
668 {
Jamie Madille0472f32018-11-27 16:32:45 -0500669 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400670 return false;
671 }
672 else
673 {
Jamie Madille0472f32018-11-27 16:32:45 -0500674 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400675 return false;
676 }
677 break;
678 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
679 if (context->getExtensions().textureCompressionDXT3)
680 {
Jamie Madille0472f32018-11-27 16:32:45 -0500681 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400682 return false;
683 }
684 else
685 {
Jamie Madille0472f32018-11-27 16:32:45 -0500686 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400687 return false;
688 }
689 break;
690 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
691 if (context->getExtensions().textureCompressionDXT5)
692 {
Jamie Madille0472f32018-11-27 16:32:45 -0500693 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400694 return false;
695 }
696 else
697 {
Jamie Madille0472f32018-11-27 16:32:45 -0500698 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400699 return false;
700 }
701 break;
702 case GL_ETC1_RGB8_OES:
703 if (context->getExtensions().compressedETC1RGB8Texture)
704 {
Jamie Madille0472f32018-11-27 16:32:45 -0500705 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400706 return false;
707 }
708 else
709 {
Jamie Madille0472f32018-11-27 16:32:45 -0500710 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400711 return false;
712 }
713 break;
714 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
715 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
716 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
717 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
718 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
719 if (context->getExtensions().lossyETCDecode)
720 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500721 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400722 return false;
723 }
724 else
725 {
Jamie Madillc3e37312018-11-30 15:25:39 -0500726 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400727 return false;
728 }
729 break;
730 case GL_DEPTH_COMPONENT:
731 case GL_DEPTH_COMPONENT16:
732 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600733 if (context->getExtensions().depthTextureAny())
Jamie Madillbe849e42017-05-02 15:49:00 -0400734 {
Jamie Madille0472f32018-11-27 16:32:45 -0500735 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400736 return false;
737 }
738 else
739 {
Jamie Madille0472f32018-11-27 16:32:45 -0500740 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400741 return false;
742 }
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -0600743 break;
744 case GL_DEPTH_STENCIL_OES:
745 case GL_DEPTH24_STENCIL8_OES:
746 if (context->getExtensions().depthTextureAny() ||
747 context->getExtensions().packedDepthStencil)
748 {
749 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
750 return false;
751 }
752 else
753 {
754 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
755 return false;
756 }
757 break;
Jamie Madillbe849e42017-05-02 15:49:00 -0400758 default:
Jamie Madille0472f32018-11-27 16:32:45 -0500759 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400760 return false;
761 }
762 }
763
764 // If width or height is zero, it is a no-op. Return false without setting an error.
765 return (width > 0 && height > 0);
766}
767
768bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
769{
770 switch (cap)
771 {
772 // EXT_multisample_compatibility
773 case GL_MULTISAMPLE_EXT:
774 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
775 return context->getExtensions().multisampleCompatibility;
776
777 case GL_CULL_FACE:
778 case GL_POLYGON_OFFSET_FILL:
779 case GL_SAMPLE_ALPHA_TO_COVERAGE:
780 case GL_SAMPLE_COVERAGE:
781 case GL_SCISSOR_TEST:
782 case GL_STENCIL_TEST:
783 case GL_DEPTH_TEST:
784 case GL_BLEND:
785 case GL_DITHER:
786 return true;
787
788 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
789 case GL_RASTERIZER_DISCARD:
790 return (context->getClientMajorVersion() >= 3);
791
792 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
793 case GL_DEBUG_OUTPUT:
794 return context->getExtensions().debug;
795
796 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
797 return queryOnly && context->getExtensions().bindGeneratesResource;
798
799 case GL_CLIENT_ARRAYS_ANGLE:
800 return queryOnly && context->getExtensions().clientArrays;
801
802 case GL_FRAMEBUFFER_SRGB_EXT:
803 return context->getExtensions().sRGBWriteControl;
804
805 case GL_SAMPLE_MASK:
806 return context->getClientVersion() >= Version(3, 1);
807
Geoff Langb433e872017-10-05 14:01:47 -0400808 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400809 return queryOnly && context->getExtensions().robustResourceInitialization;
810
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700811 // GLES1 emulation: GLES1-specific caps
812 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700813 case GL_VERTEX_ARRAY:
814 case GL_NORMAL_ARRAY:
815 case GL_COLOR_ARRAY:
816 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700817 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700818 case GL_LIGHTING:
819 case GL_LIGHT0:
820 case GL_LIGHT1:
821 case GL_LIGHT2:
822 case GL_LIGHT3:
823 case GL_LIGHT4:
824 case GL_LIGHT5:
825 case GL_LIGHT6:
826 case GL_LIGHT7:
827 case GL_NORMALIZE:
828 case GL_RESCALE_NORMAL:
829 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700830 case GL_CLIP_PLANE0:
831 case GL_CLIP_PLANE1:
832 case GL_CLIP_PLANE2:
833 case GL_CLIP_PLANE3:
834 case GL_CLIP_PLANE4:
835 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700836 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700837 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700838 case GL_LINE_SMOOTH:
839 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700840 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700841 case GL_POINT_SIZE_ARRAY_OES:
842 return context->getClientVersion() < Version(2, 0) &&
843 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700844 case GL_TEXTURE_CUBE_MAP:
845 return context->getClientVersion() < Version(2, 0) &&
846 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700847 case GL_POINT_SPRITE_OES:
848 return context->getClientVersion() < Version(2, 0) &&
849 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400850 default:
851 return false;
852 }
853}
854
Geoff Langfc32e8b2017-05-31 14:16:59 -0400855// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
856// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400857bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400858{
859 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400860 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
861 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400862 {
863 return true;
864 }
865
866 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
867 if (c >= 9 && c <= 13)
868 {
869 return true;
870 }
871
872 return false;
873}
874
Geoff Langcab92ee2017-07-19 17:32:07 -0400875bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400876{
Geoff Langa71a98e2017-06-19 15:15:00 -0400877 for (size_t i = 0; i < len; i++)
878 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400879 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400880 {
881 return false;
882 }
883 }
884
885 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400886}
887
Geoff Langcab92ee2017-07-19 17:32:07 -0400888bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
889{
890 enum class ParseState
891 {
892 // Have not seen an ASCII non-whitespace character yet on
893 // this line. Possible that we might see a preprocessor
894 // directive.
895 BEGINING_OF_LINE,
896
897 // Have seen at least one ASCII non-whitespace character
898 // on this line.
899 MIDDLE_OF_LINE,
900
901 // Handling a preprocessor directive. Passes through all
902 // characters up to the end of the line. Disables comment
903 // processing.
904 IN_PREPROCESSOR_DIRECTIVE,
905
906 // Handling a single-line comment. The comment text is
907 // replaced with a single space.
908 IN_SINGLE_LINE_COMMENT,
909
910 // Handling a multi-line comment. Newlines are passed
911 // through to preserve line numbers.
912 IN_MULTI_LINE_COMMENT
913 };
914
915 ParseState state = ParseState::BEGINING_OF_LINE;
916 size_t pos = 0;
917
918 while (pos < len)
919 {
920 char c = str[pos];
921 char next = pos + 1 < len ? str[pos + 1] : 0;
922
923 // Check for newlines
924 if (c == '\n' || c == '\r')
925 {
926 if (state != ParseState::IN_MULTI_LINE_COMMENT)
927 {
928 state = ParseState::BEGINING_OF_LINE;
929 }
930
931 pos++;
932 continue;
933 }
934
935 switch (state)
936 {
937 case ParseState::BEGINING_OF_LINE:
938 if (c == ' ')
939 {
940 // Maintain the BEGINING_OF_LINE state until a non-space is seen
941 pos++;
942 }
943 else if (c == '#')
944 {
945 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
946 pos++;
947 }
948 else
949 {
950 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
951 state = ParseState::MIDDLE_OF_LINE;
952 }
953 break;
954
955 case ParseState::MIDDLE_OF_LINE:
956 if (c == '/' && next == '/')
957 {
958 state = ParseState::IN_SINGLE_LINE_COMMENT;
959 pos++;
960 }
961 else if (c == '/' && next == '*')
962 {
963 state = ParseState::IN_MULTI_LINE_COMMENT;
964 pos++;
965 }
966 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
967 {
968 // Skip line continuation characters
969 }
970 else if (!IsValidESSLCharacter(c))
971 {
972 return false;
973 }
974 pos++;
975 break;
976
977 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700978 // Line-continuation characters may not be permitted.
979 // Otherwise, just pass it through. Do not parse comments in this state.
980 if (!lineContinuationAllowed && c == '\\')
981 {
982 return false;
983 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400984 pos++;
985 break;
986
987 case ParseState::IN_SINGLE_LINE_COMMENT:
988 // Line-continuation characters are processed before comment processing.
989 // Advance string if a new line character is immediately behind
990 // line-continuation character.
991 if (c == '\\' && (next == '\n' || next == '\r'))
992 {
993 pos++;
994 }
995 pos++;
996 break;
997
998 case ParseState::IN_MULTI_LINE_COMMENT:
999 if (c == '*' && next == '/')
1000 {
1001 state = ParseState::MIDDLE_OF_LINE;
1002 pos++;
1003 }
1004 pos++;
1005 break;
1006 }
1007 }
1008
1009 return true;
1010}
1011
Jamie Madill5b772312018-03-08 20:28:32 -05001012bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001013{
1014 ASSERT(context->isWebGL());
1015
1016 // WebGL 1.0 [Section 6.16] GLSL Constructs
1017 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1018 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1019 {
Jamie Madille0472f32018-11-27 16:32:45 -05001020 context->validationError(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001021 return false;
1022 }
1023
1024 return true;
1025}
1026
Jamie Madill5b772312018-03-08 20:28:32 -05001027bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001028{
1029 ASSERT(context->isWebGL());
1030
1031 if (context->isWebGL1() && length > 256)
1032 {
1033 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1034 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1035 // locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001036 context->validationError(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001037
1038 return false;
1039 }
1040 else if (length > 1024)
1041 {
1042 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1043 // uniform and attribute locations.
Jamie Madille0472f32018-11-27 16:32:45 -05001044 context->validationError(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001045 return false;
1046 }
1047
1048 return true;
1049}
1050
Jamie Madill007530e2017-12-28 14:27:04 -05001051bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1052{
1053 if (!context->getExtensions().pathRendering)
1054 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001055 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05001056 return false;
1057 }
1058
1059 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1060 {
Jamie Madille0472f32018-11-27 16:32:45 -05001061 context->validationError(GL_INVALID_ENUM, kInvalidMatrixMode);
Jamie Madill007530e2017-12-28 14:27:04 -05001062 return false;
1063 }
1064 return true;
1065}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001066
1067bool ValidBlendFunc(const Context *context, GLenum val)
1068{
1069 const gl::Extensions &ext = context->getExtensions();
1070
1071 // these are always valid for src and dst.
1072 switch (val)
1073 {
1074 case GL_ZERO:
1075 case GL_ONE:
1076 case GL_SRC_COLOR:
1077 case GL_ONE_MINUS_SRC_COLOR:
1078 case GL_DST_COLOR:
1079 case GL_ONE_MINUS_DST_COLOR:
1080 case GL_SRC_ALPHA:
1081 case GL_ONE_MINUS_SRC_ALPHA:
1082 case GL_DST_ALPHA:
1083 case GL_ONE_MINUS_DST_ALPHA:
1084 case GL_CONSTANT_COLOR:
1085 case GL_ONE_MINUS_CONSTANT_COLOR:
1086 case GL_CONSTANT_ALPHA:
1087 case GL_ONE_MINUS_CONSTANT_ALPHA:
1088 return true;
1089
1090 // EXT_blend_func_extended.
1091 case GL_SRC1_COLOR_EXT:
1092 case GL_SRC1_ALPHA_EXT:
1093 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1094 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1095 case GL_SRC_ALPHA_SATURATE_EXT:
1096 return ext.blendFuncExtended;
1097
1098 default:
1099 return false;
1100 }
1101}
1102
1103bool ValidSrcBlendFunc(const Context *context, GLenum val)
1104{
1105 if (ValidBlendFunc(context, val))
1106 return true;
1107
1108 if (val == GL_SRC_ALPHA_SATURATE)
1109 return true;
1110
1111 return false;
1112}
1113
1114bool ValidDstBlendFunc(const Context *context, GLenum val)
1115{
1116 if (ValidBlendFunc(context, val))
1117 return true;
1118
1119 if (val == GL_SRC_ALPHA_SATURATE)
1120 {
1121 if (context->getClientMajorVersion() >= 3)
1122 return true;
1123 }
1124
1125 return false;
1126}
Jamie Madillc29968b2016-01-20 11:17:23 -05001127} // anonymous namespace
1128
Geoff Langff5b2d52016-09-07 11:32:23 -04001129bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001130 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001131 GLint level,
1132 GLenum internalformat,
1133 bool isCompressed,
1134 bool isSubImage,
1135 GLint xoffset,
1136 GLint yoffset,
1137 GLsizei width,
1138 GLsizei height,
1139 GLint border,
1140 GLenum format,
1141 GLenum type,
1142 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001143 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001144{
Jamie Madill6f38f822014-06-06 17:12:20 -04001145 if (!ValidTexture2DDestinationTarget(context, target))
1146 {
Jamie Madille0472f32018-11-27 16:32:45 -05001147 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001148 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001149 }
1150
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001151 TextureType texType = TextureTargetToType(target);
1152 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001153 {
Jamie Madill610640f2018-11-21 17:28:41 -05001154 // Error already handled.
Geoff Langb1196682014-07-23 13:47:29 -04001155 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001156 }
1157
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001158 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001159 {
Jamie Madille0472f32018-11-27 16:32:45 -05001160 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Brandon Jones6cad5662017-06-14 13:25:13 -07001161 return false;
1162 }
1163
1164 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001165 std::numeric_limits<GLsizei>::max() - yoffset < height)
1166 {
Jamie Madille0472f32018-11-27 16:32:45 -05001167 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001168 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001169 }
1170
Geoff Langaae65a42014-05-26 12:43:44 -04001171 const gl::Caps &caps = context->getCaps();
1172
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001173 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001175 case TextureType::_2D:
1176 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1177 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1178 {
Jamie Madille0472f32018-11-27 16:32:45 -05001179 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001180 return false;
1181 }
1182 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001183
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001184 case TextureType::Rectangle:
1185 ASSERT(level == 0);
1186 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1187 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1188 {
Jamie Madille0472f32018-11-27 16:32:45 -05001189 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001190 return false;
1191 }
1192 if (isCompressed)
1193 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001194 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001195 return false;
1196 }
1197 break;
1198
1199 case TextureType::CubeMap:
1200 if (!isSubImage && width != height)
1201 {
Jamie Madille0472f32018-11-27 16:32:45 -05001202 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001203 return false;
1204 }
1205
1206 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1207 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1208 {
Jamie Madille0472f32018-11-27 16:32:45 -05001209 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001210 return false;
1211 }
1212 break;
1213
1214 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001215 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001216 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001217 }
1218
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001219 gl::Texture *texture = context->getTextureByType(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001220 if (!texture)
1221 {
Jamie Madille0472f32018-11-27 16:32:45 -05001222 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001223 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001224 }
1225
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001226 // Verify zero border
1227 if (border != 0)
1228 {
Jamie Madille0472f32018-11-27 16:32:45 -05001229 context->validationError(GL_INVALID_VALUE, kInvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001230 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001231 }
1232
Tim Van Patten208af3e2019-03-19 09:15:55 -06001233 bool nonEqualFormatsAllowed = false;
1234
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001235 if (isCompressed)
1236 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001237 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001238 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1239 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001240
1241 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1242
1243 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001244 {
Jamie Madille0472f32018-11-27 16:32:45 -05001245 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001246 return false;
1247 }
1248
1249 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1250 context->getExtensions()))
1251 {
Jamie Madille0472f32018-11-27 16:32:45 -05001252 context->validationError(GL_INVALID_ENUM, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001253 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001254 }
Geoff Lang966c9402017-04-18 12:38:27 -04001255
1256 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001257 {
Geoff Lange88e4542018-05-03 15:05:57 -04001258 // From the OES_compressed_ETC1_RGB8_texture spec:
1259 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1260 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1261 // ETC1_RGB8_OES.
1262 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1263 {
Jamie Madille0472f32018-11-27 16:32:45 -05001264 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lange88e4542018-05-03 15:05:57 -04001265 return false;
1266 }
1267
Geoff Lang966c9402017-04-18 12:38:27 -04001268 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1269 height, texture->getWidth(target, level),
1270 texture->getHeight(target, level)))
1271 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001272 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001273 return false;
1274 }
1275
1276 if (format != actualInternalFormat)
1277 {
Jamie Madille0472f32018-11-27 16:32:45 -05001278 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001279 return false;
1280 }
1281 }
1282 else
1283 {
1284 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1285 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001286 context->validationError(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
Geoff Lang966c9402017-04-18 12:38:27 -04001287 return false;
1288 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001289 }
1290 }
1291 else
1292 {
1293 // validate <type> by itself (used as secondary key below)
1294 switch (type)
1295 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 case GL_UNSIGNED_BYTE:
1297 case GL_UNSIGNED_SHORT_5_6_5:
1298 case GL_UNSIGNED_SHORT_4_4_4_4:
1299 case GL_UNSIGNED_SHORT_5_5_5_1:
1300 case GL_UNSIGNED_SHORT:
1301 case GL_UNSIGNED_INT:
1302 case GL_UNSIGNED_INT_24_8_OES:
1303 case GL_HALF_FLOAT_OES:
1304 case GL_FLOAT:
1305 break;
1306 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001307 context->validationError(GL_INVALID_ENUM, kInvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001308 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001309 }
1310
1311 // validate <format> + <type> combinations
1312 // - invalid <format> -> sets INVALID_ENUM
1313 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1314 switch (format)
1315 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001316 case GL_ALPHA:
1317 case GL_LUMINANCE:
1318 case GL_LUMINANCE_ALPHA:
1319 switch (type)
1320 {
1321 case GL_UNSIGNED_BYTE:
1322 case GL_FLOAT:
1323 case GL_HALF_FLOAT_OES:
1324 break;
1325 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001326 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001327 return false;
1328 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001330 case GL_RED:
1331 case GL_RG:
1332 if (!context->getExtensions().textureRG)
1333 {
Jamie Madille0472f32018-11-27 16:32:45 -05001334 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001335 return false;
1336 }
1337 switch (type)
1338 {
1339 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001340 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001341 case GL_FLOAT:
1342 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001343 if (!context->getExtensions().textureFloat)
1344 {
Jamie Madille0472f32018-11-27 16:32:45 -05001345 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001346 return false;
1347 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 break;
1349 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001350 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 return false;
1352 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001353 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001354 case GL_RGB:
1355 switch (type)
1356 {
1357 case GL_UNSIGNED_BYTE:
1358 case GL_UNSIGNED_SHORT_5_6_5:
1359 case GL_FLOAT:
1360 case GL_HALF_FLOAT_OES:
1361 break;
1362 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001363 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001364 return false;
1365 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001366 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 case GL_RGBA:
1368 switch (type)
1369 {
1370 case GL_UNSIGNED_BYTE:
1371 case GL_UNSIGNED_SHORT_4_4_4_4:
1372 case GL_UNSIGNED_SHORT_5_5_5_1:
1373 case GL_FLOAT:
1374 case GL_HALF_FLOAT_OES:
1375 break;
1376 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001377 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001378 return false;
1379 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001380 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001381 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001382 if (!context->getExtensions().textureFormatBGRA8888)
1383 {
Jamie Madille0472f32018-11-27 16:32:45 -05001384 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001385 return false;
1386 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001387 switch (type)
1388 {
1389 case GL_UNSIGNED_BYTE:
1390 break;
1391 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001392 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001393 return false;
1394 }
1395 break;
1396 case GL_SRGB_EXT:
1397 case GL_SRGB_ALPHA_EXT:
1398 if (!context->getExtensions().sRGB)
1399 {
Jamie Madille0472f32018-11-27 16:32:45 -05001400 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001401 return false;
1402 }
1403 switch (type)
1404 {
1405 case GL_UNSIGNED_BYTE:
1406 break;
1407 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001408 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001409 return false;
1410 }
1411 break;
1412 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1413 // handled below
1414 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1415 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1416 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1417 break;
1418 case GL_DEPTH_COMPONENT:
1419 switch (type)
1420 {
1421 case GL_UNSIGNED_SHORT:
1422 case GL_UNSIGNED_INT:
1423 break;
1424 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001425 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 return false;
1427 }
1428 break;
1429 case GL_DEPTH_STENCIL_OES:
1430 switch (type)
1431 {
1432 case GL_UNSIGNED_INT_24_8_OES:
1433 break;
1434 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001435 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001436 return false;
1437 }
1438 break;
1439 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001440 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001441 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001442 }
1443
1444 switch (format)
1445 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001446 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1447 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1448 if (context->getExtensions().textureCompressionDXT1)
1449 {
Jamie Madille0472f32018-11-27 16:32:45 -05001450 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 else
1454 {
Jamie Madille0472f32018-11-27 16:32:45 -05001455 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 break;
1459 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1460 if (context->getExtensions().textureCompressionDXT3)
1461 {
Jamie Madille0472f32018-11-27 16:32:45 -05001462 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001463 return false;
1464 }
1465 else
1466 {
Jamie Madille0472f32018-11-27 16:32:45 -05001467 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1472 if (context->getExtensions().textureCompressionDXT5)
1473 {
Jamie Madille0472f32018-11-27 16:32:45 -05001474 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001475 return false;
1476 }
1477 else
1478 {
Jamie Madille0472f32018-11-27 16:32:45 -05001479 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 break;
1483 case GL_ETC1_RGB8_OES:
1484 if (context->getExtensions().compressedETC1RGB8Texture)
1485 {
Jamie Madille0472f32018-11-27 16:32:45 -05001486 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001487 return false;
1488 }
1489 else
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 break;
1495 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001496 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1497 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1498 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1499 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001500 if (context->getExtensions().lossyETCDecode)
1501 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001502 context->validationError(GL_INVALID_OPERATION, kInvalidFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001503 return false;
1504 }
1505 else
1506 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001507 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001508 return false;
1509 }
1510 break;
1511 case GL_DEPTH_COMPONENT:
1512 case GL_DEPTH_STENCIL_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001513 if (!context->getExtensions().depthTextureANGLE &&
1514 !(context->getExtensions().packedDepthStencil &&
1515 context->getExtensions().depthTextureOES))
He Yunchaoced53ae2016-11-29 15:00:51 +08001516 {
Jamie Madille0472f32018-11-27 16:32:45 -05001517 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001518 return false;
1519 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001520 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001521 {
Jamie Madille0472f32018-11-27 16:32:45 -05001522 context->validationError(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001523 return false;
1524 }
1525 // OES_depth_texture supports loading depth data and multiple levels,
1526 // but ANGLE_depth_texture does not
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001527 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001528 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001529 if (pixels != nullptr)
1530 {
1531 context->validationError(GL_INVALID_OPERATION, kPixelDataNotNull);
1532 return false;
1533 }
1534 if (level != 0)
1535 {
1536 context->validationError(GL_INVALID_OPERATION, kLevelNotZero);
1537 return false;
1538 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001539 }
1540 break;
1541 default:
1542 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001543 }
1544
Geoff Lang6e898aa2017-06-02 11:17:26 -04001545 if (!isSubImage)
1546 {
1547 switch (internalformat)
1548 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001549 // Core ES 2.0 formats
1550 case GL_ALPHA:
1551 case GL_LUMINANCE:
1552 case GL_LUMINANCE_ALPHA:
1553 case GL_RGB:
1554 case GL_RGBA:
1555 break;
1556
Geoff Lang6e898aa2017-06-02 11:17:26 -04001557 case GL_RGBA32F:
1558 if (!context->getExtensions().colorBufferFloatRGBA)
1559 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001560 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001561 return false;
1562 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001563
1564 nonEqualFormatsAllowed = true;
1565
Geoff Lang6e898aa2017-06-02 11:17:26 -04001566 if (type != GL_FLOAT)
1567 {
Jamie Madille0472f32018-11-27 16:32:45 -05001568 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001569 return false;
1570 }
1571 if (format != GL_RGBA)
1572 {
Jamie Madille0472f32018-11-27 16:32:45 -05001573 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001574 return false;
1575 }
1576 break;
1577
1578 case GL_RGB32F:
1579 if (!context->getExtensions().colorBufferFloatRGB)
1580 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001581 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001582 return false;
1583 }
Tim Van Patten208af3e2019-03-19 09:15:55 -06001584
1585 nonEqualFormatsAllowed = true;
1586
Geoff Lang6e898aa2017-06-02 11:17:26 -04001587 if (type != GL_FLOAT)
1588 {
Jamie Madille0472f32018-11-27 16:32:45 -05001589 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001590 return false;
1591 }
1592 if (format != GL_RGB)
1593 {
Jamie Madille0472f32018-11-27 16:32:45 -05001594 context->validationError(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001595 return false;
1596 }
1597 break;
1598
Tim Van Patten208af3e2019-03-19 09:15:55 -06001599 case GL_BGRA_EXT:
1600 if (!context->getExtensions().textureFormatBGRA8888)
1601 {
1602 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1603 return false;
1604 }
Geoff Lang6e898aa2017-06-02 11:17:26 -04001605 break;
Tim Van Patten208af3e2019-03-19 09:15:55 -06001606
1607 case GL_DEPTH_COMPONENT:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001608 if (!(context->getExtensions().depthTextureAny()))
1609 {
1610 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1611 return false;
1612 }
1613 break;
1614
Tim Van Patten208af3e2019-03-19 09:15:55 -06001615 case GL_DEPTH_STENCIL:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001616 if (!(context->getExtensions().depthTextureANGLE ||
1617 context->getExtensions().packedDepthStencil))
Tim Van Patten208af3e2019-03-19 09:15:55 -06001618 {
1619 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1620 return false;
1621 }
1622 break;
1623
1624 case GL_RED:
1625 case GL_RG:
1626 if (!context->getExtensions().textureRG)
1627 {
1628 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
1629 return false;
1630 }
1631 break;
1632
1633 case GL_SRGB_EXT:
1634 case GL_SRGB_ALPHA_EXT:
1635 if (!context->getExtensions().sRGB)
1636 {
1637 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1638 return false;
1639 }
1640 break;
1641
1642 default:
1643 context->validationError(GL_INVALID_VALUE, kInvalidInternalFormat);
1644 return false;
Geoff Lang6e898aa2017-06-02 11:17:26 -04001645 }
1646 }
1647
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001648 if (type == GL_FLOAT)
1649 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001650 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001651 {
Jamie Madille0472f32018-11-27 16:32:45 -05001652 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001653 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001654 }
1655 }
1656 else if (type == GL_HALF_FLOAT_OES)
1657 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001658 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001659 {
Jamie Madille0472f32018-11-27 16:32:45 -05001660 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001661 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001662 }
1663 }
1664 }
1665
Tim Van Patten208af3e2019-03-19 09:15:55 -06001666 if (isSubImage)
Geoff Langff5b2d52016-09-07 11:32:23 -04001667 {
Tim Van Patten208af3e2019-03-19 09:15:55 -06001668 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1669 if (textureInternalFormat.internalFormat == GL_NONE)
1670 {
1671 context->validationError(GL_INVALID_OPERATION, kInvalidTextureLevel);
1672 return false;
1673 }
1674
Tim Van Patten5f388c22019-03-14 09:54:23 -06001675 if (format != textureInternalFormat.format)
1676 {
1677 context->validationError(GL_INVALID_OPERATION, err::kTextureFormatMismatch);
1678 return false;
1679 }
1680
1681 if (context->getExtensions().webglCompatibility)
Tim Van Patten208af3e2019-03-19 09:15:55 -06001682 {
1683 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1684 textureInternalFormat.sizedInternalFormat)
1685 {
Tim Van Patten5f388c22019-03-14 09:54:23 -06001686 context->validationError(GL_INVALID_OPERATION, kTextureTypeMismatch);
Tim Van Patten208af3e2019-03-19 09:15:55 -06001687 return false;
1688 }
1689 }
1690
1691 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1692 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1693 {
1694 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
1695 return false;
1696 }
1697
1698 if (width > 0 && height > 0 && pixels == nullptr &&
1699 context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1700 {
1701 context->validationError(GL_INVALID_VALUE, kPixelDataNull);
1702 return false;
1703 }
1704 }
1705 else
1706 {
1707 if (texture->getImmutableFormat())
1708 {
1709 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
1710 return false;
1711 }
1712 }
1713
1714 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1715 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1716 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1717 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1718 // case.
1719 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1720 {
1721 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Langff5b2d52016-09-07 11:32:23 -04001722 return false;
1723 }
1724
Tim Van Patten208af3e2019-03-19 09:15:55 -06001725 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1726 return ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
1727 imageSize);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001728}
1729
He Yunchaoced53ae2016-11-29 15:00:51 +08001730bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001731 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001732 GLsizei levels,
1733 GLenum internalformat,
1734 GLsizei width,
1735 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001736{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001737 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1738 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001739 {
Jamie Madille0472f32018-11-27 16:32:45 -05001740 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001741 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001742 }
1743
1744 if (width < 1 || height < 1 || levels < 1)
1745 {
Jamie Madille0472f32018-11-27 16:32:45 -05001746 context->validationError(GL_INVALID_VALUE, kTextureSizeTooSmall);
Geoff Langb1196682014-07-23 13:47:29 -04001747 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001748 }
1749
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001750 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001751 {
Jamie Madille0472f32018-11-27 16:32:45 -05001752 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Langb1196682014-07-23 13:47:29 -04001753 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001754 }
1755
1756 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1757 {
Jamie Madille0472f32018-11-27 16:32:45 -05001758 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
Geoff Langb1196682014-07-23 13:47:29 -04001759 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001760 }
1761
Geoff Langca271392017-04-05 12:30:00 -04001762 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001763 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001764 {
Jamie Madille0472f32018-11-27 16:32:45 -05001765 context->validationError(GL_INVALID_ENUM, kInvalidFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001766 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001767 }
1768
Geoff Langaae65a42014-05-26 12:43:44 -04001769 const gl::Caps &caps = context->getCaps();
1770
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001771 switch (target)
1772 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001773 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1775 static_cast<GLuint>(height) > caps.max2DTextureSize)
1776 {
Jamie Madille0472f32018-11-27 16:32:45 -05001777 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001778 return false;
1779 }
1780 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001781 case TextureType::Rectangle:
Jamie Madill610640f2018-11-21 17:28:41 -05001782 if (levels != 1)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001783 {
Jamie Madille0472f32018-11-27 16:32:45 -05001784 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madill610640f2018-11-21 17:28:41 -05001785 return false;
1786 }
1787
1788 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1789 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1790 {
Jamie Madille0472f32018-11-27 16:32:45 -05001791 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001792 return false;
1793 }
1794 if (formatInfo.compressed)
1795 {
Jamie Madille0472f32018-11-27 16:32:45 -05001796 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001797 return false;
1798 }
1799 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001800 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001801 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1802 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1803 {
Jamie Madille0472f32018-11-27 16:32:45 -05001804 context->validationError(GL_INVALID_VALUE, kResourceMaxTextureSize);
He Yunchaoced53ae2016-11-29 15:00:51 +08001805 return false;
1806 }
1807 break;
1808 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001809 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Langb1196682014-07-23 13:47:29 -04001810 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001811 }
1812
Geoff Langc0b9ef42014-07-02 10:02:37 -04001813 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001814 {
1815 if (!gl::isPow2(width) || !gl::isPow2(height))
1816 {
Jamie Madille0472f32018-11-27 16:32:45 -05001817 context->validationError(GL_INVALID_OPERATION, kDimensionsMustBePow2);
Geoff Langb1196682014-07-23 13:47:29 -04001818 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001819 }
1820 }
1821
1822 switch (internalformat)
1823 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001824 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1825 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1826 if (!context->getExtensions().textureCompressionDXT1)
1827 {
Jamie Madille0472f32018-11-27 16:32:45 -05001828 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 return false;
1830 }
1831 break;
1832 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1833 if (!context->getExtensions().textureCompressionDXT3)
1834 {
Jamie Madille0472f32018-11-27 16:32:45 -05001835 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001836 return false;
1837 }
1838 break;
1839 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1840 if (!context->getExtensions().textureCompressionDXT5)
1841 {
Jamie Madille0472f32018-11-27 16:32:45 -05001842 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001843 return false;
1844 }
1845 break;
1846 case GL_ETC1_RGB8_OES:
1847 if (!context->getExtensions().compressedETC1RGB8Texture)
1848 {
Jamie Madille0472f32018-11-27 16:32:45 -05001849 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001850 return false;
1851 }
1852 break;
1853 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001854 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1855 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1856 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1857 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001858 if (!context->getExtensions().lossyETCDecode)
1859 {
Jamie Madillc3e37312018-11-30 15:25:39 -05001860 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001861 return false;
1862 }
1863 break;
1864 case GL_RGBA32F_EXT:
1865 case GL_RGB32F_EXT:
1866 case GL_ALPHA32F_EXT:
1867 case GL_LUMINANCE32F_EXT:
1868 case GL_LUMINANCE_ALPHA32F_EXT:
1869 if (!context->getExtensions().textureFloat)
1870 {
Jamie Madille0472f32018-11-27 16:32:45 -05001871 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001872 return false;
1873 }
1874 break;
1875 case GL_RGBA16F_EXT:
1876 case GL_RGB16F_EXT:
1877 case GL_ALPHA16F_EXT:
1878 case GL_LUMINANCE16F_EXT:
1879 case GL_LUMINANCE_ALPHA16F_EXT:
1880 if (!context->getExtensions().textureHalfFloat)
1881 {
Jamie Madille0472f32018-11-27 16:32:45 -05001882 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001883 return false;
1884 }
1885 break;
1886 case GL_R8_EXT:
1887 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001888 if (!context->getExtensions().textureRG)
1889 {
Jamie Madille0472f32018-11-27 16:32:45 -05001890 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001891 return false;
1892 }
1893 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001894 case GL_R16F_EXT:
1895 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001896 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1897 {
Jamie Madille0472f32018-11-27 16:32:45 -05001898 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang677bb6f2017-04-05 12:40:40 -04001899 return false;
1900 }
1901 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001902 case GL_R32F_EXT:
1903 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001904 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001905 {
Jamie Madille0472f32018-11-27 16:32:45 -05001906 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001907 return false;
1908 }
1909 break;
1910 case GL_DEPTH_COMPONENT16:
1911 case GL_DEPTH_COMPONENT32_OES:
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001912 if (!(context->getExtensions().depthTextureAny()))
He Yunchaoced53ae2016-11-29 15:00:51 +08001913 {
Jamie Madille0472f32018-11-27 16:32:45 -05001914 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
He Yunchaoced53ae2016-11-29 15:00:51 +08001915 return false;
1916 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001917 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001918 {
Jamie Madille0472f32018-11-27 16:32:45 -05001919 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001920 return false;
1921 }
1922 // ANGLE_depth_texture only supports 1-level textures
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001923 if (!context->getExtensions().depthTextureOES)
He Yunchaoced53ae2016-11-29 15:00:51 +08001924 {
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001925 if (levels != 1)
1926 {
1927 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
1928 return false;
1929 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001930 }
1931 break;
Courtney Goeltzenleuchtereaf2d922019-04-18 16:31:25 -06001932 case GL_DEPTH24_STENCIL8_OES:
1933 if (!(context->getExtensions().depthTextureANGLE ||
1934 (context->getExtensions().packedDepthStencil &&
1935 context->getExtensions().textureStorage)))
1936 {
1937 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
1938 return false;
1939 }
1940 if (target != TextureType::_2D)
1941 {
1942 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
1943 return false;
1944 }
1945 if (!context->getExtensions().packedDepthStencil)
1946 {
1947 // ANGLE_depth_texture only supports 1-level textures
1948 if (levels != 1)
1949 {
1950 context->validationError(GL_INVALID_OPERATION, kInvalidMipLevels);
1951 return false;
1952 }
1953 }
1954 break;
1955
He Yunchaoced53ae2016-11-29 15:00:51 +08001956 default:
1957 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001958 }
1959
Jamie Madillcfc73cc2019-04-08 16:26:51 -04001960 gl::Texture *texture = context->getTextureByType(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001961 if (!texture || texture->id() == 0)
1962 {
Jamie Madille0472f32018-11-27 16:32:45 -05001963 context->validationError(GL_INVALID_OPERATION, kMissingTexture);
Geoff Langb1196682014-07-23 13:47:29 -04001964 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001965 }
1966
Geoff Lang69cce582015-09-17 13:20:36 -04001967 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001968 {
Jamie Madille0472f32018-11-27 16:32:45 -05001969 context->validationError(GL_INVALID_OPERATION, kTextureIsImmutable);
Geoff Langb1196682014-07-23 13:47:29 -04001970 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001971 }
1972
1973 return true;
1974}
1975
He Yunchaoced53ae2016-11-29 15:00:51 +08001976bool ValidateDiscardFramebufferEXT(Context *context,
1977 GLenum target,
1978 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001979 const GLenum *attachments)
1980{
Jamie Madillc29968b2016-01-20 11:17:23 -05001981 if (!context->getExtensions().discardFramebuffer)
1982 {
Jamie Madille0472f32018-11-27 16:32:45 -05001983 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001984 return false;
1985 }
1986
Austin Kinross08332632015-05-05 13:35:47 -07001987 bool defaultFramebuffer = false;
1988
1989 switch (target)
1990 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001991 case GL_FRAMEBUFFER:
1992 defaultFramebuffer =
Jamie Madillc3dc5d42018-12-30 12:12:04 -05001993 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
He Yunchaoced53ae2016-11-29 15:00:51 +08001994 break;
1995 default:
Jamie Madille0472f32018-11-27 16:32:45 -05001996 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001997 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001998 }
1999
He Yunchaoced53ae2016-11-29 15:00:51 +08002000 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
2001 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07002002}
2003
Austin Kinrossbc781f32015-10-26 09:27:38 -07002004bool ValidateBindVertexArrayOES(Context *context, GLuint array)
2005{
2006 if (!context->getExtensions().vertexArrayObject)
2007 {
Jamie Madille0472f32018-11-27 16:32:45 -05002008 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002009 return false;
2010 }
2011
2012 return ValidateBindVertexArrayBase(context, array);
2013}
2014
Jamie Madilld7576732017-08-26 18:49:50 -04002015bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002016{
2017 if (!context->getExtensions().vertexArrayObject)
2018 {
Jamie Madille0472f32018-11-27 16:32:45 -05002019 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002020 return false;
2021 }
2022
Olli Etuaho41997e72016-03-10 13:38:39 +02002023 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002024}
2025
Jamie Madilld7576732017-08-26 18:49:50 -04002026bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002027{
2028 if (!context->getExtensions().vertexArrayObject)
2029 {
Jamie Madille0472f32018-11-27 16:32:45 -05002030 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002031 return false;
2032 }
2033
Olli Etuaho41997e72016-03-10 13:38:39 +02002034 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002035}
2036
Jamie Madilld7576732017-08-26 18:49:50 -04002037bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07002038{
2039 if (!context->getExtensions().vertexArrayObject)
2040 {
Jamie Madille0472f32018-11-27 16:32:45 -05002041 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07002042 return false;
2043 }
2044
2045 return true;
2046}
Geoff Langc5629752015-12-07 16:29:04 -05002047
2048bool ValidateProgramBinaryOES(Context *context,
2049 GLuint program,
2050 GLenum binaryFormat,
2051 const void *binary,
2052 GLint length)
2053{
2054 if (!context->getExtensions().getProgramBinary)
2055 {
Jamie Madille0472f32018-11-27 16:32:45 -05002056 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002057 return false;
2058 }
2059
2060 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2061}
2062
2063bool ValidateGetProgramBinaryOES(Context *context,
2064 GLuint program,
2065 GLsizei bufSize,
2066 GLsizei *length,
2067 GLenum *binaryFormat,
2068 void *binary)
2069{
2070 if (!context->getExtensions().getProgramBinary)
2071 {
Jamie Madille0472f32018-11-27 16:32:45 -05002072 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002073 return false;
2074 }
2075
2076 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2077}
Geoff Lange102fee2015-12-10 11:23:30 -05002078
Geoff Lang70d0f492015-12-10 17:45:46 -05002079static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2080{
2081 switch (source)
2082 {
2083 case GL_DEBUG_SOURCE_API:
2084 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2085 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2086 case GL_DEBUG_SOURCE_OTHER:
2087 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2088 return !mustBeThirdPartyOrApplication;
2089
2090 case GL_DEBUG_SOURCE_THIRD_PARTY:
2091 case GL_DEBUG_SOURCE_APPLICATION:
2092 return true;
2093
2094 default:
2095 return false;
2096 }
2097}
2098
2099static bool ValidDebugType(GLenum type)
2100{
2101 switch (type)
2102 {
2103 case GL_DEBUG_TYPE_ERROR:
2104 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2105 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2106 case GL_DEBUG_TYPE_PERFORMANCE:
2107 case GL_DEBUG_TYPE_PORTABILITY:
2108 case GL_DEBUG_TYPE_OTHER:
2109 case GL_DEBUG_TYPE_MARKER:
2110 case GL_DEBUG_TYPE_PUSH_GROUP:
2111 case GL_DEBUG_TYPE_POP_GROUP:
2112 return true;
2113
2114 default:
2115 return false;
2116 }
2117}
2118
2119static bool ValidDebugSeverity(GLenum severity)
2120{
2121 switch (severity)
2122 {
2123 case GL_DEBUG_SEVERITY_HIGH:
2124 case GL_DEBUG_SEVERITY_MEDIUM:
2125 case GL_DEBUG_SEVERITY_LOW:
2126 case GL_DEBUG_SEVERITY_NOTIFICATION:
2127 return true;
2128
2129 default:
2130 return false;
2131 }
2132}
2133
Geoff Lange102fee2015-12-10 11:23:30 -05002134bool ValidateDebugMessageControlKHR(Context *context,
2135 GLenum source,
2136 GLenum type,
2137 GLenum severity,
2138 GLsizei count,
2139 const GLuint *ids,
2140 GLboolean enabled)
2141{
2142 if (!context->getExtensions().debug)
2143 {
Jamie Madille0472f32018-11-27 16:32:45 -05002144 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002145 return false;
2146 }
2147
Geoff Lang70d0f492015-12-10 17:45:46 -05002148 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2149 {
Jamie Madille0472f32018-11-27 16:32:45 -05002150 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002151 return false;
2152 }
2153
2154 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2155 {
Jamie Madille0472f32018-11-27 16:32:45 -05002156 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002157 return false;
2158 }
2159
2160 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2161 {
Jamie Madille0472f32018-11-27 16:32:45 -05002162 context->validationError(GL_INVALID_ENUM, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002163 return false;
2164 }
2165
2166 if (count > 0)
2167 {
2168 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2169 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002170 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSourceType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002171 return false;
2172 }
2173
2174 if (severity != GL_DONT_CARE)
2175 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002176 context->validationError(GL_INVALID_OPERATION, kInvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002177 return false;
2178 }
2179 }
2180
Geoff Lange102fee2015-12-10 11:23:30 -05002181 return true;
2182}
2183
2184bool ValidateDebugMessageInsertKHR(Context *context,
2185 GLenum source,
2186 GLenum type,
2187 GLuint id,
2188 GLenum severity,
2189 GLsizei length,
2190 const GLchar *buf)
2191{
2192 if (!context->getExtensions().debug)
2193 {
Jamie Madille0472f32018-11-27 16:32:45 -05002194 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002195 return false;
2196 }
2197
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002198 if (!context->getState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002199 {
2200 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2201 // not generate an error.
2202 return false;
2203 }
2204
2205 if (!ValidDebugSeverity(severity))
2206 {
Jamie Madille0472f32018-11-27 16:32:45 -05002207 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002208 return false;
2209 }
2210
2211 if (!ValidDebugType(type))
2212 {
Jamie Madille0472f32018-11-27 16:32:45 -05002213 context->validationError(GL_INVALID_ENUM, kInvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002214 return false;
2215 }
2216
2217 if (!ValidDebugSource(source, true))
2218 {
Jamie Madille0472f32018-11-27 16:32:45 -05002219 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002220 return false;
2221 }
2222
2223 size_t messageLength = (length < 0) ? strlen(buf) : length;
2224 if (messageLength > context->getExtensions().maxDebugMessageLength)
2225 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002226 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 return false;
2228 }
2229
Geoff Lange102fee2015-12-10 11:23:30 -05002230 return true;
2231}
2232
2233bool ValidateDebugMessageCallbackKHR(Context *context,
2234 GLDEBUGPROCKHR callback,
2235 const void *userParam)
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 Lange102fee2015-12-10 11:23:30 -05002243 return true;
2244}
2245
2246bool ValidateGetDebugMessageLogKHR(Context *context,
2247 GLuint count,
2248 GLsizei bufSize,
2249 GLenum *sources,
2250 GLenum *types,
2251 GLuint *ids,
2252 GLenum *severities,
2253 GLsizei *lengths,
2254 GLchar *messageLog)
2255{
2256 if (!context->getExtensions().debug)
2257 {
Jamie Madille0472f32018-11-27 16:32:45 -05002258 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002259 return false;
2260 }
2261
Geoff Lang70d0f492015-12-10 17:45:46 -05002262 if (bufSize < 0 && messageLog != nullptr)
2263 {
Jamie Madille0472f32018-11-27 16:32:45 -05002264 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002265 return false;
2266 }
2267
Geoff Lange102fee2015-12-10 11:23:30 -05002268 return true;
2269}
2270
2271bool ValidatePushDebugGroupKHR(Context *context,
2272 GLenum source,
2273 GLuint id,
2274 GLsizei length,
2275 const GLchar *message)
2276{
2277 if (!context->getExtensions().debug)
2278 {
Jamie Madille0472f32018-11-27 16:32:45 -05002279 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002280 return false;
2281 }
2282
Geoff Lang70d0f492015-12-10 17:45:46 -05002283 if (!ValidDebugSource(source, true))
2284 {
Jamie Madille0472f32018-11-27 16:32:45 -05002285 context->validationError(GL_INVALID_ENUM, kInvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002286 return false;
2287 }
2288
2289 size_t messageLength = (length < 0) ? strlen(message) : length;
2290 if (messageLength > context->getExtensions().maxDebugMessageLength)
2291 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002292 context->validationError(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 return false;
2294 }
2295
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002296 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002297 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2298 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002299 context->validationError(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
Geoff Lang70d0f492015-12-10 17:45:46 -05002300 return false;
2301 }
2302
Geoff Lange102fee2015-12-10 11:23:30 -05002303 return true;
2304}
2305
2306bool ValidatePopDebugGroupKHR(Context *context)
2307{
2308 if (!context->getExtensions().debug)
2309 {
Jamie Madille0472f32018-11-27 16:32:45 -05002310 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002311 return false;
2312 }
2313
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002314 size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002315 if (currentStackSize <= 1)
2316 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002317 context->validationError(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
Geoff Lang70d0f492015-12-10 17:45:46 -05002318 return false;
2319 }
2320
2321 return true;
2322}
2323
2324static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2325{
2326 switch (identifier)
2327 {
2328 case GL_BUFFER:
2329 if (context->getBuffer(name) == nullptr)
2330 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002331 context->validationError(GL_INVALID_VALUE, kInvalidBufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002332 return false;
2333 }
2334 return true;
2335
2336 case GL_SHADER:
2337 if (context->getShader(name) == nullptr)
2338 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002339 context->validationError(GL_INVALID_VALUE, kInvalidShaderName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002340 return false;
2341 }
2342 return true;
2343
2344 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002345 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002346 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002347 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002348 return false;
2349 }
2350 return true;
2351
2352 case GL_VERTEX_ARRAY:
2353 if (context->getVertexArray(name) == nullptr)
2354 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002355 context->validationError(GL_INVALID_VALUE, kInvalidVertexArrayName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 return false;
2357 }
2358 return true;
2359
2360 case GL_QUERY:
2361 if (context->getQuery(name) == nullptr)
2362 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002363 context->validationError(GL_INVALID_VALUE, kInvalidQueryName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002364 return false;
2365 }
2366 return true;
2367
2368 case GL_TRANSFORM_FEEDBACK:
2369 if (context->getTransformFeedback(name) == nullptr)
2370 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002371 context->validationError(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002372 return false;
2373 }
2374 return true;
2375
2376 case GL_SAMPLER:
2377 if (context->getSampler(name) == nullptr)
2378 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002379 context->validationError(GL_INVALID_VALUE, kInvalidSamplerName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002380 return false;
2381 }
2382 return true;
2383
2384 case GL_TEXTURE:
2385 if (context->getTexture(name) == nullptr)
2386 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002387 context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002388 return false;
2389 }
2390 return true;
2391
2392 case GL_RENDERBUFFER:
2393 if (context->getRenderbuffer(name) == nullptr)
2394 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002395 context->validationError(GL_INVALID_VALUE, kInvalidRenderbufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002396 return false;
2397 }
2398 return true;
2399
2400 case GL_FRAMEBUFFER:
2401 if (context->getFramebuffer(name) == nullptr)
2402 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002403 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferName);
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 return false;
2405 }
2406 return true;
2407
2408 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05002409 context->validationError(GL_INVALID_ENUM, kInvalidIndentifier);
Geoff Lang70d0f492015-12-10 17:45:46 -05002410 return false;
2411 }
Geoff Lange102fee2015-12-10 11:23:30 -05002412}
2413
Martin Radev9d901792016-07-15 15:58:58 +03002414static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2415{
2416 size_t labelLength = 0;
2417
2418 if (length < 0)
2419 {
2420 if (label != nullptr)
2421 {
2422 labelLength = strlen(label);
2423 }
2424 }
2425 else
2426 {
2427 labelLength = static_cast<size_t>(length);
2428 }
2429
2430 if (labelLength > context->getExtensions().maxLabelLength)
2431 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002432 context->validationError(GL_INVALID_VALUE, kExceedsMaxLabelLength);
Martin Radev9d901792016-07-15 15:58:58 +03002433 return false;
2434 }
2435
2436 return true;
2437}
2438
Geoff Lange102fee2015-12-10 11:23:30 -05002439bool ValidateObjectLabelKHR(Context *context,
2440 GLenum identifier,
2441 GLuint name,
2442 GLsizei length,
2443 const GLchar *label)
2444{
2445 if (!context->getExtensions().debug)
2446 {
Jamie Madille0472f32018-11-27 16:32:45 -05002447 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002448 return false;
2449 }
2450
Geoff Lang70d0f492015-12-10 17:45:46 -05002451 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2452 {
2453 return false;
2454 }
2455
Martin Radev9d901792016-07-15 15:58:58 +03002456 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002457 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002458 return false;
2459 }
2460
Geoff Lange102fee2015-12-10 11:23:30 -05002461 return true;
2462}
2463
2464bool ValidateGetObjectLabelKHR(Context *context,
2465 GLenum identifier,
2466 GLuint name,
2467 GLsizei bufSize,
2468 GLsizei *length,
2469 GLchar *label)
2470{
2471 if (!context->getExtensions().debug)
2472 {
Jamie Madille0472f32018-11-27 16:32:45 -05002473 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002474 return false;
2475 }
2476
Geoff Lang70d0f492015-12-10 17:45:46 -05002477 if (bufSize < 0)
2478 {
Jamie Madille0472f32018-11-27 16:32:45 -05002479 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002480 return false;
2481 }
2482
2483 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2484 {
2485 return false;
2486 }
2487
Martin Radev9d901792016-07-15 15:58:58 +03002488 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002489}
2490
2491static bool ValidateObjectPtrName(Context *context, const void *ptr)
2492{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002493 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002494 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002495 context->validationError(GL_INVALID_VALUE, kInvalidSyncPointer);
Geoff Lang70d0f492015-12-10 17:45:46 -05002496 return false;
2497 }
2498
Geoff Lange102fee2015-12-10 11:23:30 -05002499 return true;
2500}
2501
2502bool ValidateObjectPtrLabelKHR(Context *context,
2503 const void *ptr,
2504 GLsizei length,
2505 const GLchar *label)
2506{
2507 if (!context->getExtensions().debug)
2508 {
Jamie Madille0472f32018-11-27 16:32:45 -05002509 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002510 return false;
2511 }
2512
Geoff Lang70d0f492015-12-10 17:45:46 -05002513 if (!ValidateObjectPtrName(context, ptr))
2514 {
2515 return false;
2516 }
2517
Martin Radev9d901792016-07-15 15:58:58 +03002518 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002519 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002520 return false;
2521 }
2522
Geoff Lange102fee2015-12-10 11:23:30 -05002523 return true;
2524}
2525
2526bool ValidateGetObjectPtrLabelKHR(Context *context,
2527 const void *ptr,
2528 GLsizei bufSize,
2529 GLsizei *length,
2530 GLchar *label)
2531{
2532 if (!context->getExtensions().debug)
2533 {
Jamie Madille0472f32018-11-27 16:32:45 -05002534 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002535 return false;
2536 }
2537
Geoff Lang70d0f492015-12-10 17:45:46 -05002538 if (bufSize < 0)
2539 {
Jamie Madille0472f32018-11-27 16:32:45 -05002540 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002541 return false;
2542 }
2543
2544 if (!ValidateObjectPtrName(context, ptr))
2545 {
2546 return false;
2547 }
2548
Martin Radev9d901792016-07-15 15:58:58 +03002549 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002550}
2551
2552bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2553{
2554 if (!context->getExtensions().debug)
2555 {
Jamie Madille0472f32018-11-27 16:32:45 -05002556 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002557 return false;
2558 }
2559
Geoff Lang70d0f492015-12-10 17:45:46 -05002560 // TODO: represent this in Context::getQueryParameterInfo.
2561 switch (pname)
2562 {
2563 case GL_DEBUG_CALLBACK_FUNCTION:
2564 case GL_DEBUG_CALLBACK_USER_PARAM:
2565 break;
2566
2567 default:
Jamie Madille0472f32018-11-27 16:32:45 -05002568 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002569 return false;
2570 }
2571
Geoff Lange102fee2015-12-10 11:23:30 -05002572 return true;
2573}
Jamie Madillc29968b2016-01-20 11:17:23 -05002574
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002575bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2576 GLenum pname,
2577 GLsizei bufSize,
2578 GLsizei *length,
2579 void **params)
2580{
2581 UNIMPLEMENTED();
2582 return false;
2583}
2584
Jamie Madillc29968b2016-01-20 11:17:23 -05002585bool ValidateBlitFramebufferANGLE(Context *context,
2586 GLint srcX0,
2587 GLint srcY0,
2588 GLint srcX1,
2589 GLint srcY1,
2590 GLint dstX0,
2591 GLint dstY0,
2592 GLint dstX1,
2593 GLint dstY1,
2594 GLbitfield mask,
2595 GLenum filter)
2596{
2597 if (!context->getExtensions().framebufferBlit)
2598 {
Jamie Madille0472f32018-11-27 16:32:45 -05002599 context->validationError(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002600 return false;
2601 }
2602
2603 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2604 {
2605 // TODO(jmadill): Determine if this should be available on other implementations.
Jamie Madille0472f32018-11-27 16:32:45 -05002606 context->validationError(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002607 return false;
2608 }
2609
2610 if (filter == GL_LINEAR)
2611 {
Jamie Madille0472f32018-11-27 16:32:45 -05002612 context->validationError(GL_INVALID_ENUM, kBlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002613 return false;
2614 }
2615
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002616 Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2617 Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002618
2619 if (mask & GL_COLOR_BUFFER_BIT)
2620 {
2621 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2622 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2623
2624 if (readColorAttachment && drawColorAttachment)
2625 {
2626 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002627 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002628 readColorAttachment->type() != GL_RENDERBUFFER &&
2629 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2630 {
Jamie Madill610640f2018-11-21 17:28:41 -05002631 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002632 kBlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002633 return false;
2634 }
2635
Geoff Langa15472a2015-08-11 11:48:03 -04002636 for (size_t drawbufferIdx = 0;
2637 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002638 {
Geoff Langa15472a2015-08-11 11:48:03 -04002639 const FramebufferAttachment *attachment =
2640 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2641 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002642 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002643 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002644 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002645 attachment->type() != GL_RENDERBUFFER &&
2646 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2647 {
Jamie Madill610640f2018-11-21 17:28:41 -05002648 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002649 kBlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002650 return false;
2651 }
2652
2653 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002654 if (!Format::EquivalentForBlit(attachment->getFormat(),
2655 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002656 {
Jamie Madill610640f2018-11-21 17:28:41 -05002657 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002658 kBlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002659 return false;
2660 }
2661 }
2662 }
2663
Jamie Madill427064d2018-04-13 16:20:34 -04002664 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002665 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002666 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2667 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2668 {
Jamie Madill610640f2018-11-21 17:28:41 -05002669 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002670 kBlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002671 return false;
2672 }
2673 }
2674 }
2675
2676 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2677 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2678 for (size_t i = 0; i < 2; i++)
2679 {
2680 if (mask & masks[i])
2681 {
2682 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002683 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002684 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002685 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002686
2687 if (readBuffer && drawBuffer)
2688 {
2689 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2690 dstX0, dstY0, dstX1, dstY1))
2691 {
2692 // only whole-buffer copies are permitted
Jamie Madill610640f2018-11-21 17:28:41 -05002693 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002694 kBlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002695 return false;
2696 }
2697
2698 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2699 {
Jamie Madill610640f2018-11-21 17:28:41 -05002700 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05002701 kBlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002702 return false;
2703 }
2704 }
2705 }
2706 }
2707
2708 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2709 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002710}
Jamie Madillc29968b2016-01-20 11:17:23 -05002711
Jamie Madill5b772312018-03-08 20:28:32 -05002712bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002713{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002714 Framebuffer *fbo = context->getState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002715 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002716
Jamie Madill427064d2018-04-13 16:20:34 -04002717 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002718 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002719 return false;
2720 }
2721
2722 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2723 {
Jamie Madille0472f32018-11-27 16:32:45 -05002724 context->validationError(GL_INVALID_VALUE, kInvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002725 return false;
2726 }
2727
Olli Etuaho94c91a92018-07-19 15:10:24 +03002728 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002729 {
2730 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2731 GL_SIGNED_NORMALIZED};
2732
Corentin Wallez59c41592017-07-11 13:19:54 -04002733 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002734 drawBufferIdx++)
2735 {
2736 if (!ValidateWebGLFramebufferAttachmentClearType(
2737 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2738 {
2739 return false;
2740 }
2741 }
2742 }
2743
Mingyu Huebab6702019-04-19 14:36:45 -07002744 if ((extensions.multiview || extensions.multiview2) && extensions.disjointTimerQuery)
Olli Etuaho94c91a92018-07-19 15:10:24 +03002745 {
Jamie Madillc3dc5d42018-12-30 12:12:04 -05002746 const State &state = context->getState();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002747 Framebuffer *framebuffer = state.getDrawFramebuffer();
2748 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2749 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002750 context->validationError(GL_INVALID_OPERATION, kMultiviewTimerQuery);
Olli Etuaho94c91a92018-07-19 15:10:24 +03002751 return false;
2752 }
2753 }
2754
Jamie Madillc29968b2016-01-20 11:17:23 -05002755 return true;
2756}
2757
Jamie Madill5b772312018-03-08 20:28:32 -05002758bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002759{
2760 if (!context->getExtensions().drawBuffers)
2761 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002762 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05002763 return false;
2764 }
2765
2766 return ValidateDrawBuffersBase(context, n, bufs);
2767}
2768
Jamie Madill73a84962016-02-12 09:27:23 -05002769bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002770 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002771 GLint level,
2772 GLint internalformat,
2773 GLsizei width,
2774 GLsizei height,
2775 GLint border,
2776 GLenum format,
2777 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002778 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002779{
Martin Radev1be913c2016-07-11 17:59:16 +03002780 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002781 {
2782 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002783 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002784 }
2785
Martin Radev1be913c2016-07-11 17:59:16 +03002786 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002787 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002788 0, 0, width, height, 1, border, format, type, -1,
2789 pixels);
2790}
2791
Brandon Jones416aaf92018-04-10 08:10:16 -07002792bool ValidateTexImage2DRobustANGLE(Context *context,
2793 TextureTarget target,
2794 GLint level,
2795 GLint internalformat,
2796 GLsizei width,
2797 GLsizei height,
2798 GLint border,
2799 GLenum format,
2800 GLenum type,
2801 GLsizei bufSize,
2802 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002803{
2804 if (!ValidateRobustEntryPoint(context, bufSize))
2805 {
2806 return false;
2807 }
2808
2809 if (context->getClientMajorVersion() < 3)
2810 {
2811 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2812 0, 0, width, height, border, format, type, bufSize,
2813 pixels);
2814 }
2815
2816 ASSERT(context->getClientMajorVersion() >= 3);
2817 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2818 0, 0, width, height, 1, border, format, type, bufSize,
2819 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002820}
2821
2822bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002823 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002824 GLint level,
2825 GLint xoffset,
2826 GLint yoffset,
2827 GLsizei width,
2828 GLsizei height,
2829 GLenum format,
2830 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002831 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002832{
2833
Martin Radev1be913c2016-07-11 17:59:16 +03002834 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002835 {
2836 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002837 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002838 }
2839
Martin Radev1be913c2016-07-11 17:59:16 +03002840 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002841 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002842 yoffset, 0, width, height, 1, 0, format, type, -1,
2843 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002844}
2845
Geoff Langc52f6f12016-10-14 10:18:00 -04002846bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002847 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002848 GLint level,
2849 GLint xoffset,
2850 GLint yoffset,
2851 GLsizei width,
2852 GLsizei height,
2853 GLenum format,
2854 GLenum type,
2855 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002856 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002857{
2858 if (!ValidateRobustEntryPoint(context, bufSize))
2859 {
2860 return false;
2861 }
2862
2863 if (context->getClientMajorVersion() < 3)
2864 {
2865 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2866 yoffset, width, height, 0, format, type, bufSize,
2867 pixels);
2868 }
2869
2870 ASSERT(context->getClientMajorVersion() >= 3);
2871 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2872 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2873 pixels);
2874}
2875
Jamie Madill73a84962016-02-12 09:27:23 -05002876bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002877 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002878 GLint level,
2879 GLenum internalformat,
2880 GLsizei width,
2881 GLsizei height,
2882 GLint border,
2883 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002884 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002885{
Martin Radev1be913c2016-07-11 17:59:16 +03002886 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002887 {
2888 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002889 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002890 {
2891 return false;
2892 }
2893 }
2894 else
2895 {
Martin Radev1be913c2016-07-11 17:59:16 +03002896 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002897 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002898 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002899 data))
2900 {
2901 return false;
2902 }
2903 }
2904
Geoff Langca271392017-04-05 12:30:00 -04002905 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002906
2907 GLuint blockSize = 0;
2908 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002909 {
Jamie Madille0472f32018-11-27 16:32:45 -05002910 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002911 return false;
2912 }
2913
Jamie Madillca2ff382018-07-11 09:01:17 -04002914 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002915 {
Jamie Madille0472f32018-11-27 16:32:45 -05002916 context->validationError(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002917 return false;
2918 }
2919
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002920 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002921 {
Jamie Madillc3e37312018-11-30 15:25:39 -05002922 context->validationError(GL_INVALID_ENUM, kRectangleTextureCompressed);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002923 return false;
2924 }
2925
Jamie Madill73a84962016-02-12 09:27:23 -05002926 return true;
2927}
2928
Corentin Wallezb2931602017-04-11 15:58:57 -04002929bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002930 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002931 GLint level,
2932 GLenum internalformat,
2933 GLsizei width,
2934 GLsizei height,
2935 GLint border,
2936 GLsizei imageSize,
2937 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002938 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002939{
2940 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2941 {
2942 return false;
2943 }
2944
2945 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2946 border, imageSize, data);
2947}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002948
Corentin Wallezb2931602017-04-11 15:58:57 -04002949bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002950 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002951 GLint level,
2952 GLint xoffset,
2953 GLint yoffset,
2954 GLsizei width,
2955 GLsizei height,
2956 GLenum format,
2957 GLsizei imageSize,
2958 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002959 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002960{
2961 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2962 {
2963 return false;
2964 }
2965
2966 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2967 format, imageSize, data);
2968}
2969
Jamie Madill73a84962016-02-12 09:27:23 -05002970bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002971 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002972 GLint level,
2973 GLint xoffset,
2974 GLint yoffset,
2975 GLsizei width,
2976 GLsizei height,
2977 GLenum format,
2978 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002979 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002980{
Martin Radev1be913c2016-07-11 17:59:16 +03002981 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002982 {
2983 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002984 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002985 {
2986 return false;
2987 }
2988 }
2989 else
2990 {
Martin Radev1be913c2016-07-11 17:59:16 +03002991 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002992 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002993 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002994 data))
2995 {
2996 return false;
2997 }
2998 }
2999
Geoff Langca271392017-04-05 12:30:00 -04003000 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04003001 GLuint blockSize = 0;
3002 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04003003 {
Jamie Madille0472f32018-11-27 16:32:45 -05003004 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04003005 return false;
3006 }
3007
Jamie Madillca2ff382018-07-11 09:01:17 -04003008 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05003009 {
Jamie Madille0472f32018-11-27 16:32:45 -05003010 context->validationError(GL_INVALID_VALUE, kInvalidCompressedImageSize);
Jamie Madill73a84962016-02-12 09:27:23 -05003011 return false;
3012 }
3013
3014 return true;
3015}
3016
Corentin Wallez336129f2017-10-17 15:55:40 -04003017bool ValidateGetBufferPointervOES(Context *context,
3018 BufferBinding target,
3019 GLenum pname,
3020 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03003021{
Jamie Madillc3e37312018-11-30 15:25:39 -05003022 if (!context->getExtensions().mapBuffer)
3023 {
3024 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3025 return false;
3026 }
3027
Geoff Lang496c02d2016-10-20 11:38:11 -07003028 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03003029}
3030
Corentin Wallez336129f2017-10-17 15:55:40 -04003031bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03003032{
3033 if (!context->getExtensions().mapBuffer)
3034 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003035 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003036 return false;
3037 }
3038
Corentin Walleze4477002017-12-01 14:39:58 -05003039 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03003040 {
Jamie Madille0472f32018-11-27 16:32:45 -05003041 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03003042 return false;
3043 }
3044
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003045 Buffer *buffer = context->getState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003046
3047 if (buffer == nullptr)
3048 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003049 context->validationError(GL_INVALID_OPERATION, kBufferNotMappable);
Olli Etuaho4f667482016-03-30 15:56:35 +03003050 return false;
3051 }
3052
3053 if (access != GL_WRITE_ONLY_OES)
3054 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003055 context->validationError(GL_INVALID_ENUM, kInvalidAccessBits);
Olli Etuaho4f667482016-03-30 15:56:35 +03003056 return false;
3057 }
3058
3059 if (buffer->isMapped())
3060 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003061 context->validationError(GL_INVALID_OPERATION, kBufferAlreadyMapped);
Olli Etuaho4f667482016-03-30 15:56:35 +03003062 return false;
3063 }
3064
Geoff Lang79f71042017-08-14 16:43:43 -04003065 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003066}
3067
Corentin Wallez336129f2017-10-17 15:55:40 -04003068bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003069{
3070 if (!context->getExtensions().mapBuffer)
3071 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003072 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003073 return false;
3074 }
3075
3076 return ValidateUnmapBufferBase(context, target);
3077}
3078
3079bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003080 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003081 GLintptr offset,
3082 GLsizeiptr length,
3083 GLbitfield access)
3084{
3085 if (!context->getExtensions().mapBufferRange)
3086 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003087 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003088 return false;
3089 }
3090
3091 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3092}
3093
Michael Spang7a8c3e52019-04-03 14:49:57 -04003094bool ValidateBufferStorageMemEXT(Context *context,
3095 TextureType target,
3096 GLsizeiptr size,
3097 GLuint memory,
3098 GLuint64 offset)
3099{
3100 if (!context->getExtensions().memoryObject)
3101 {
3102 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3103 return false;
3104 }
3105
3106 UNIMPLEMENTED();
3107 return false;
3108}
3109
3110bool ValidateCreateMemoryObjectsEXT(Context *context, GLsizei n, GLuint *memoryObjects)
3111{
3112 if (!context->getExtensions().memoryObject)
3113 {
3114 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3115 return false;
3116 }
3117
Michael Spangfb201c52019-04-03 14:57:35 -04003118 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003119}
3120
3121bool ValidateDeleteMemoryObjectsEXT(Context *context, GLsizei n, const GLuint *memoryObjects)
3122{
3123 if (!context->getExtensions().memoryObject)
3124 {
3125 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3126 return false;
3127 }
3128
Michael Spangfb201c52019-04-03 14:57:35 -04003129 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003130}
3131
3132bool ValidateGetMemoryObjectParameterivEXT(Context *context,
3133 GLuint memoryObject,
3134 GLenum pname,
3135 GLint *params)
3136{
3137 if (!context->getExtensions().memoryObject)
3138 {
3139 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3140 return false;
3141 }
3142
3143 UNIMPLEMENTED();
3144 return false;
3145}
3146
3147bool ValidateGetUnsignedBytevEXT(Context *context, GLenum pname, GLubyte *data)
3148{
3149 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3150 {
3151 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3152 return false;
3153 }
3154
3155 UNIMPLEMENTED();
3156 return false;
3157}
3158
3159bool ValidateGetUnsignedBytei_vEXT(Context *context, GLenum target, GLuint index, GLubyte *data)
3160{
3161 if (!context->getExtensions().memoryObject && !context->getExtensions().semaphore)
3162 {
3163 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3164 return false;
3165 }
3166
3167 UNIMPLEMENTED();
3168 return false;
3169}
3170
3171bool ValidateIsMemoryObjectEXT(Context *context, GLuint memoryObject)
3172{
3173 if (!context->getExtensions().memoryObject)
3174 {
3175 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3176 return false;
3177 }
3178
Michael Spangfb201c52019-04-03 14:57:35 -04003179 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003180}
3181
3182bool ValidateMemoryObjectParameterivEXT(Context *context,
3183 GLuint memoryObject,
3184 GLenum pname,
3185 const GLint *params)
3186{
3187 if (!context->getExtensions().memoryObject)
3188 {
3189 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3190 return false;
3191 }
3192
3193 UNIMPLEMENTED();
3194 return false;
3195}
3196
3197bool ValidateTexStorageMem2DEXT(Context *context,
3198 TextureType target,
3199 GLsizei levels,
3200 GLenum internalFormat,
3201 GLsizei width,
3202 GLsizei height,
3203 GLuint memory,
3204 GLuint64 offset)
3205{
3206 if (!context->getExtensions().memoryObject)
3207 {
3208 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3209 return false;
3210 }
3211
Michael Spangf02a7672019-04-09 18:45:23 -04003212 if (context->getClientMajorVersion() < 3)
3213 {
3214 return ValidateES2TexStorageParameters(context, target, levels, internalFormat, width,
3215 height);
3216 }
3217
3218 ASSERT(context->getClientMajorVersion() >= 3);
3219 return ValidateES3TexStorage2DParameters(context, target, levels, internalFormat, width, height,
3220 1);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003221}
3222
3223bool ValidateTexStorageMem3DEXT(Context *context,
3224 TextureType target,
3225 GLsizei levels,
3226 GLenum internalFormat,
3227 GLsizei width,
3228 GLsizei height,
3229 GLsizei depth,
3230 GLuint memory,
3231 GLuint64 offset)
3232{
3233 if (!context->getExtensions().memoryObject)
3234 {
3235 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3236 return false;
3237 }
3238
3239 UNIMPLEMENTED();
3240 return false;
3241}
3242
Michael Spang9de3ddb2019-04-03 16:23:40 -04003243bool ValidateImportMemoryFdEXT(Context *context,
3244 GLuint memory,
3245 GLuint64 size,
Michael Spange0da9ce2019-04-16 14:34:51 -04003246 HandleType handleType,
Michael Spang9de3ddb2019-04-03 16:23:40 -04003247 GLint fd)
3248{
3249 if (!context->getExtensions().memoryObjectFd)
3250 {
3251 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3252 return false;
3253 }
3254
Michael Spang3b2c6bf2019-04-16 17:19:50 -04003255 switch (handleType)
3256 {
3257 case HandleType::OpaqueFd:
3258 break;
3259 default:
3260 context->validationError(GL_INVALID_ENUM, kInvalidHandleType);
3261 return false;
3262 }
3263
3264 return true;
Michael Spang9de3ddb2019-04-03 16:23:40 -04003265}
3266
Michael Spang7a8c3e52019-04-03 14:49:57 -04003267bool ValidateDeleteSemaphoresEXT(Context *context, GLsizei n, const GLuint *semaphores)
3268{
3269 if (!context->getExtensions().semaphore)
3270 {
3271 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3272 return false;
3273 }
3274
Michael Spang5093ba62019-05-14 17:36:36 -04003275 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003276}
3277
3278bool ValidateGenSemaphoresEXT(Context *context, GLsizei n, GLuint *semaphores)
3279{
3280 if (!context->getExtensions().semaphore)
3281 {
3282 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3283 return false;
3284 }
3285
Michael Spang5093ba62019-05-14 17:36:36 -04003286 return ValidateGenOrDelete(context, n);
Michael Spang7a8c3e52019-04-03 14:49:57 -04003287}
3288
3289bool ValidateGetSemaphoreParameterui64vEXT(Context *context,
3290 GLuint semaphore,
3291 GLenum pname,
3292 GLuint64 *params)
3293{
3294 if (!context->getExtensions().semaphore)
3295 {
3296 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3297 return false;
3298 }
3299
3300 UNIMPLEMENTED();
3301 return false;
3302}
3303
3304bool ValidateIsSemaphoreEXT(Context *context, GLuint semaphore)
3305{
3306 if (!context->getExtensions().semaphore)
3307 {
3308 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3309 return false;
3310 }
3311
Michael Spang5093ba62019-05-14 17:36:36 -04003312 return true;
Michael Spang7a8c3e52019-04-03 14:49:57 -04003313}
3314
3315bool ValidateSemaphoreParameterui64vEXT(Context *context,
3316 GLuint semaphore,
3317 GLenum pname,
3318 const GLuint64 *params)
3319{
3320 if (!context->getExtensions().semaphore)
3321 {
3322 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3323 return false;
3324 }
3325
3326 UNIMPLEMENTED();
3327 return false;
3328}
3329
3330bool ValidateSignalSemaphoreEXT(Context *context,
3331 GLuint semaphore,
3332 GLuint numBufferBarriers,
3333 const GLuint *buffers,
3334 GLuint numTextureBarriers,
3335 const GLuint *textures,
3336 const GLenum *dstLayouts)
3337{
3338 if (!context->getExtensions().semaphore)
3339 {
3340 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3341 return false;
3342 }
3343
3344 UNIMPLEMENTED();
3345 return false;
3346}
3347
3348bool ValidateWaitSemaphoreEXT(Context *context,
3349 GLuint semaphore,
3350 GLuint numBufferBarriers,
3351 const GLuint *buffers,
3352 GLuint numTextureBarriers,
3353 const GLuint *textures,
3354 const GLenum *srcLayouts)
3355{
3356 if (!context->getExtensions().semaphore)
3357 {
3358 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3359 return false;
3360 }
3361
3362 UNIMPLEMENTED();
3363 return false;
3364}
3365
Michael Spange0da9ce2019-04-16 14:34:51 -04003366bool ValidateImportSemaphoreFdEXT(Context *context,
3367 GLuint semaphore,
3368 HandleType handleType,
3369 GLint fd)
Michael Spang9de3ddb2019-04-03 16:23:40 -04003370{
3371 if (!context->getExtensions().semaphoreFd)
3372 {
3373 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
3374 return false;
3375 }
3376
3377 UNIMPLEMENTED();
3378 return false;
3379}
3380
Corentin Wallez336129f2017-10-17 15:55:40 -04003381bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003382{
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003383 Buffer *buffer = context->getState().getTargetBuffer(target);
Geoff Lang79f71042017-08-14 16:43:43 -04003384 ASSERT(buffer != nullptr);
3385
3386 // Check if this buffer is currently being used as a transform feedback output buffer
Jamie Madillc3dc5d42018-12-30 12:12:04 -05003387 TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
Geoff Lang79f71042017-08-14 16:43:43 -04003388 if (transformFeedback != nullptr && transformFeedback->isActive())
3389 {
3390 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3391 {
3392 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3393 if (transformFeedbackBuffer.get() == buffer)
3394 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003395 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
Geoff Lang79f71042017-08-14 16:43:43 -04003396 return false;
3397 }
3398 }
3399 }
3400
James Darpiniane8a93c62018-01-04 18:02:24 -08003401 if (context->getExtensions().webglCompatibility &&
3402 buffer->isBoundForTransformFeedbackAndOtherUse())
3403 {
Jamie Madille0472f32018-11-27 16:32:45 -05003404 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08003405 return false;
3406 }
3407
Geoff Lang79f71042017-08-14 16:43:43 -04003408 return true;
3409}
3410
Olli Etuaho4f667482016-03-30 15:56:35 +03003411bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003412 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003413 GLintptr offset,
3414 GLsizeiptr length)
3415{
3416 if (!context->getExtensions().mapBufferRange)
3417 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003418 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Olli Etuaho4f667482016-03-30 15:56:35 +03003419 return false;
3420 }
3421
3422 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3423}
3424
Geoff Langd8605522016-04-13 10:19:12 -04003425bool ValidateBindUniformLocationCHROMIUM(Context *context,
3426 GLuint program,
3427 GLint location,
3428 const GLchar *name)
3429{
3430 if (!context->getExtensions().bindUniformLocation)
3431 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003432 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langd8605522016-04-13 10:19:12 -04003433 return false;
3434 }
3435
3436 Program *programObject = GetValidProgram(context, program);
3437 if (!programObject)
3438 {
3439 return false;
3440 }
3441
3442 if (location < 0)
3443 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003444 context->validationError(GL_INVALID_VALUE, kNegativeLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003445 return false;
3446 }
3447
3448 const Caps &caps = context->getCaps();
3449 if (static_cast<size_t>(location) >=
3450 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3451 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003452 context->validationError(GL_INVALID_VALUE, kInvalidBindUniformLocation);
Geoff Langd8605522016-04-13 10:19:12 -04003453 return false;
3454 }
3455
Geoff Langfc32e8b2017-05-31 14:16:59 -04003456 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3457 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003458 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003459 {
Jamie Madille0472f32018-11-27 16:32:45 -05003460 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003461 return false;
3462 }
3463
Geoff Langd8605522016-04-13 10:19:12 -04003464 if (strncmp(name, "gl_", 3) == 0)
3465 {
Jamie Madille0472f32018-11-27 16:32:45 -05003466 context->validationError(GL_INVALID_VALUE, kNameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003467 return false;
3468 }
3469
3470 return true;
3471}
3472
Jamie Madille2e406c2016-06-02 13:04:10 -04003473bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003474{
3475 if (!context->getExtensions().framebufferMixedSamples)
3476 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003477 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänena797e062016-05-12 15:23:40 +03003478 return false;
3479 }
3480 switch (components)
3481 {
3482 case GL_RGB:
3483 case GL_RGBA:
3484 case GL_ALPHA:
3485 case GL_NONE:
3486 break;
3487 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003488 context->validationError(GL_INVALID_ENUM, kInvalidCoverageComponents);
Sami Väisänena797e062016-05-12 15:23:40 +03003489 return false;
3490 }
3491
3492 return true;
3493}
3494
Sami Väisänene45e53b2016-05-25 10:36:04 +03003495// CHROMIUM_path_rendering
3496
Jamie Madill007530e2017-12-28 14:27:04 -05003497bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003498{
Jamie Madill007530e2017-12-28 14:27:04 -05003499 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003501 return false;
3502 }
Jamie Madill007530e2017-12-28 14:27:04 -05003503
Sami Väisänene45e53b2016-05-25 10:36:04 +03003504 if (matrix == nullptr)
3505 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003506 context->validationError(GL_INVALID_OPERATION, kInvalidPathMatrix);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507 return false;
3508 }
Jamie Madill007530e2017-12-28 14:27:04 -05003509
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510 return true;
3511}
3512
Jamie Madill007530e2017-12-28 14:27:04 -05003513bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003514{
Jamie Madill007530e2017-12-28 14:27:04 -05003515 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003516}
3517
Jamie Madill007530e2017-12-28 14:27:04 -05003518bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519{
3520 if (!context->getExtensions().pathRendering)
3521 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003522 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003523 return false;
3524 }
3525
3526 // range = 0 is undefined in NV_path_rendering.
3527 // we add stricter semantic check here and require a non zero positive range.
3528 if (range <= 0)
3529 {
Jamie Madille0472f32018-11-27 16:32:45 -05003530 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003531 return false;
3532 }
3533
3534 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3535 {
Jamie Madille0472f32018-11-27 16:32:45 -05003536 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003537 return false;
3538 }
3539
3540 return true;
3541}
3542
Jamie Madill007530e2017-12-28 14:27:04 -05003543bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003544{
3545 if (!context->getExtensions().pathRendering)
3546 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003547 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003548 return false;
3549 }
3550
3551 // range = 0 is undefined in NV_path_rendering.
3552 // we add stricter semantic check here and require a non zero positive range.
3553 if (range <= 0)
3554 {
Jamie Madille0472f32018-11-27 16:32:45 -05003555 context->validationError(GL_INVALID_VALUE, kInvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003556 return false;
3557 }
3558
3559 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3560 checkedRange += range;
3561
3562 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3563 {
Jamie Madille0472f32018-11-27 16:32:45 -05003564 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003565 return false;
3566 }
3567 return true;
3568}
3569
Jamie Madill007530e2017-12-28 14:27:04 -05003570bool ValidatePathCommandsCHROMIUM(Context *context,
3571 GLuint path,
3572 GLsizei numCommands,
3573 const GLubyte *commands,
3574 GLsizei numCoords,
3575 GLenum coordType,
3576 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003577{
3578 if (!context->getExtensions().pathRendering)
3579 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003580 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003581 return false;
3582 }
Brandon Jones59770802018-04-02 13:18:42 -07003583 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003584 {
Jamie Madille0472f32018-11-27 16:32:45 -05003585 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003586 return false;
3587 }
3588
3589 if (numCommands < 0)
3590 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003591 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCommands);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003592 return false;
3593 }
3594 else if (numCommands > 0)
3595 {
3596 if (!commands)
3597 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003598 context->validationError(GL_INVALID_VALUE, kInvalidPathCommandsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003599 return false;
3600 }
3601 }
3602
3603 if (numCoords < 0)
3604 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003605 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003606 return false;
3607 }
3608 else if (numCoords > 0)
3609 {
3610 if (!coords)
3611 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003612 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoordsArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003613 return false;
3614 }
3615 }
3616
3617 std::uint32_t coordTypeSize = 0;
3618 switch (coordType)
3619 {
3620 case GL_BYTE:
3621 coordTypeSize = sizeof(GLbyte);
3622 break;
3623
3624 case GL_UNSIGNED_BYTE:
3625 coordTypeSize = sizeof(GLubyte);
3626 break;
3627
3628 case GL_SHORT:
3629 coordTypeSize = sizeof(GLshort);
3630 break;
3631
3632 case GL_UNSIGNED_SHORT:
3633 coordTypeSize = sizeof(GLushort);
3634 break;
3635
3636 case GL_FLOAT:
3637 coordTypeSize = sizeof(GLfloat);
3638 break;
3639
3640 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003641 context->validationError(GL_INVALID_ENUM, kInvalidPathCoordinateType);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003642 return false;
3643 }
3644
3645 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3646 checkedSize += (coordTypeSize * numCoords);
3647 if (!checkedSize.IsValid())
3648 {
Jamie Madille0472f32018-11-27 16:32:45 -05003649 context->validationError(GL_INVALID_OPERATION, kIntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003650 return false;
3651 }
3652
3653 // early return skips command data validation when it doesn't exist.
3654 if (!commands)
3655 return true;
3656
3657 GLsizei expectedNumCoords = 0;
3658 for (GLsizei i = 0; i < numCommands; ++i)
3659 {
3660 switch (commands[i])
3661 {
3662 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3663 break;
3664 case GL_MOVE_TO_CHROMIUM:
3665 case GL_LINE_TO_CHROMIUM:
3666 expectedNumCoords += 2;
3667 break;
3668 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3669 expectedNumCoords += 4;
3670 break;
3671 case GL_CUBIC_CURVE_TO_CHROMIUM:
3672 expectedNumCoords += 6;
3673 break;
3674 case GL_CONIC_CURVE_TO_CHROMIUM:
3675 expectedNumCoords += 5;
3676 break;
3677 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003678 context->validationError(GL_INVALID_ENUM, kInvalidPathCommand);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003679 return false;
3680 }
3681 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003682
Sami Väisänene45e53b2016-05-25 10:36:04 +03003683 if (expectedNumCoords != numCoords)
3684 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003685 context->validationError(GL_INVALID_VALUE, kInvalidPathNumCoords);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003686 return false;
3687 }
3688
3689 return true;
3690}
3691
Jamie Madill007530e2017-12-28 14:27:04 -05003692bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003693{
3694 if (!context->getExtensions().pathRendering)
3695 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003696 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003697 return false;
3698 }
Brandon Jones59770802018-04-02 13:18:42 -07003699 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003700 {
Jamie Madille0472f32018-11-27 16:32:45 -05003701 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003702 return false;
3703 }
3704
3705 switch (pname)
3706 {
3707 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3708 if (value < 0.0f)
3709 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003710 context->validationError(GL_INVALID_VALUE, kInvalidPathStrokeWidth);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003711 return false;
3712 }
3713 break;
3714 case GL_PATH_END_CAPS_CHROMIUM:
3715 switch (static_cast<GLenum>(value))
3716 {
3717 case GL_FLAT_CHROMIUM:
3718 case GL_SQUARE_CHROMIUM:
3719 case GL_ROUND_CHROMIUM:
3720 break;
3721 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003722 context->validationError(GL_INVALID_ENUM, kInvalidPathEndCaps);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003723 return false;
3724 }
3725 break;
3726 case GL_PATH_JOIN_STYLE_CHROMIUM:
3727 switch (static_cast<GLenum>(value))
3728 {
3729 case GL_MITER_REVERT_CHROMIUM:
3730 case GL_BEVEL_CHROMIUM:
3731 case GL_ROUND_CHROMIUM:
3732 break;
3733 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003734 context->validationError(GL_INVALID_ENUM, kInvalidPathJoinStyle);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003735 return false;
3736 }
Nico Weber41b072b2018-02-09 10:01:32 -05003737 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003738 case GL_PATH_MITER_LIMIT_CHROMIUM:
3739 if (value < 0.0f)
3740 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003741 context->validationError(GL_INVALID_VALUE, kInvalidPathMiterLimit);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003742 return false;
3743 }
3744 break;
3745
3746 case GL_PATH_STROKE_BOUND_CHROMIUM:
3747 // no errors, only clamping.
3748 break;
3749
3750 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003751 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003752 return false;
3753 }
3754 return true;
3755}
3756
Jamie Madill007530e2017-12-28 14:27:04 -05003757bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3758{
3759 // TODO(jmadill): Use proper clamping cast.
3760 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3761}
3762
3763bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003764{
3765 if (!context->getExtensions().pathRendering)
3766 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003767 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003768 return false;
3769 }
3770
Brandon Jones59770802018-04-02 13:18:42 -07003771 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003772 {
Jamie Madille0472f32018-11-27 16:32:45 -05003773 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003774 return false;
3775 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003776
Sami Väisänene45e53b2016-05-25 10:36:04 +03003777 if (!value)
3778 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003779 context->validationError(GL_INVALID_VALUE, kInvalidPathValueArray);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003780 return false;
3781 }
3782
3783 switch (pname)
3784 {
3785 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3786 case GL_PATH_END_CAPS_CHROMIUM:
3787 case GL_PATH_JOIN_STYLE_CHROMIUM:
3788 case GL_PATH_MITER_LIMIT_CHROMIUM:
3789 case GL_PATH_STROKE_BOUND_CHROMIUM:
3790 break;
3791
3792 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05003793 context->validationError(GL_INVALID_ENUM, kInvalidPathParameter);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003794 return false;
3795 }
3796
3797 return true;
3798}
3799
Jamie Madill007530e2017-12-28 14:27:04 -05003800bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3801{
3802 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3803 reinterpret_cast<GLfloat *>(value));
3804}
3805
3806bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003807{
3808 if (!context->getExtensions().pathRendering)
3809 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003810 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003811 return false;
3812 }
3813
3814 switch (func)
3815 {
3816 case GL_NEVER:
3817 case GL_ALWAYS:
3818 case GL_LESS:
3819 case GL_LEQUAL:
3820 case GL_EQUAL:
3821 case GL_GEQUAL:
3822 case GL_GREATER:
3823 case GL_NOTEQUAL:
3824 break;
3825 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003826 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003827 return false;
3828 }
3829
3830 return true;
3831}
3832
3833// Note that the spec specifies that for the path drawing commands
3834// if the path object is not an existing path object the command
3835// does nothing and no error is generated.
3836// However if the path object exists but has not been specified any
3837// commands then an error is generated.
3838
Jamie Madill007530e2017-12-28 14:27:04 -05003839bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003840{
3841 if (!context->getExtensions().pathRendering)
3842 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003843 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003844 return false;
3845 }
Brandon Jones59770802018-04-02 13:18:42 -07003846 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003847 {
Jamie Madille0472f32018-11-27 16:32:45 -05003848 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003849 return false;
3850 }
3851
3852 switch (fillMode)
3853 {
3854 case GL_COUNT_UP_CHROMIUM:
3855 case GL_COUNT_DOWN_CHROMIUM:
3856 break;
3857 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003858 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003859 return false;
3860 }
3861
3862 if (!isPow2(mask + 1))
3863 {
Jamie Madille0472f32018-11-27 16:32:45 -05003864 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003865 return false;
3866 }
3867
3868 return true;
3869}
3870
Jamie Madill007530e2017-12-28 14:27:04 -05003871bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003872{
3873 if (!context->getExtensions().pathRendering)
3874 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003875 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003876 return false;
3877 }
Jamie Madillc3e37312018-11-30 15:25:39 -05003878
Brandon Jones59770802018-04-02 13:18:42 -07003879 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003880 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003881 context->validationError(GL_INVALID_OPERATION, kNoPathOrNoPathData);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003882 return false;
3883 }
3884
3885 return true;
3886}
3887
Jamie Madill007530e2017-12-28 14:27:04 -05003888bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003889{
3890 if (!context->getExtensions().pathRendering)
3891 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003892 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003893 return false;
3894 }
Brandon Jones59770802018-04-02 13:18:42 -07003895 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003896 {
Jamie Madille0472f32018-11-27 16:32:45 -05003897 context->validationError(GL_INVALID_OPERATION, kNoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003898 return false;
3899 }
3900
3901 switch (coverMode)
3902 {
3903 case GL_CONVEX_HULL_CHROMIUM:
3904 case GL_BOUNDING_BOX_CHROMIUM:
3905 break;
3906 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003907 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003908 return false;
3909 }
3910 return true;
3911}
3912
Jamie Madill778bf092018-11-14 09:54:36 -05003913bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3914{
3915 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3916}
3917
3918bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3919{
3920 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3921}
3922
Jamie Madill007530e2017-12-28 14:27:04 -05003923bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3924 GLuint path,
3925 GLenum fillMode,
3926 GLuint mask,
3927 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003928{
Jamie Madill007530e2017-12-28 14:27:04 -05003929 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3930 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003931}
3932
Jamie Madill007530e2017-12-28 14:27:04 -05003933bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3934 GLuint path,
3935 GLint reference,
3936 GLuint mask,
3937 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003938{
Jamie Madill007530e2017-12-28 14:27:04 -05003939 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3940 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003941}
3942
Brandon Jonesd1049182018-03-28 10:02:20 -07003943bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003944{
3945 if (!context->getExtensions().pathRendering)
3946 {
Jamie Madillc3e37312018-11-30 15:25:39 -05003947 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003948 return false;
3949 }
3950 return true;
3951}
3952
Jamie Madill007530e2017-12-28 14:27:04 -05003953bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3954 GLsizei numPaths,
3955 GLenum pathNameType,
3956 const void *paths,
3957 GLuint pathBase,
3958 GLenum coverMode,
3959 GLenum transformType,
3960 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003961{
3962 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3963 transformType, transformValues))
3964 return false;
3965
3966 switch (coverMode)
3967 {
3968 case GL_CONVEX_HULL_CHROMIUM:
3969 case GL_BOUNDING_BOX_CHROMIUM:
3970 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3971 break;
3972 default:
Jamie Madille0472f32018-11-27 16:32:45 -05003973 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003974 return false;
3975 }
3976
3977 return true;
3978}
3979
Jamie Madill007530e2017-12-28 14:27:04 -05003980bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3981 GLsizei numPaths,
3982 GLenum pathNameType,
3983 const void *paths,
3984 GLuint pathBase,
3985 GLenum coverMode,
3986 GLenum transformType,
3987 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003988{
3989 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3990 transformType, transformValues))
3991 return false;
3992
3993 switch (coverMode)
3994 {
3995 case GL_CONVEX_HULL_CHROMIUM:
3996 case GL_BOUNDING_BOX_CHROMIUM:
3997 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3998 break;
3999 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004000 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004001 return false;
4002 }
4003
4004 return true;
4005}
4006
Jamie Madill007530e2017-12-28 14:27:04 -05004007bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
4008 GLsizei numPaths,
4009 GLenum pathNameType,
4010 const void *paths,
4011 GLuint pathBase,
4012 GLenum fillMode,
4013 GLuint mask,
4014 GLenum transformType,
4015 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004016{
4017
4018 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4019 transformType, transformValues))
4020 return false;
4021
4022 switch (fillMode)
4023 {
4024 case GL_COUNT_UP_CHROMIUM:
4025 case GL_COUNT_DOWN_CHROMIUM:
4026 break;
4027 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004028 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004029 return false;
4030 }
4031 if (!isPow2(mask + 1))
4032 {
Jamie Madille0472f32018-11-27 16:32:45 -05004033 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004034 return false;
4035 }
4036 return true;
4037}
4038
Jamie Madill007530e2017-12-28 14:27:04 -05004039bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
4040 GLsizei numPaths,
4041 GLenum pathNameType,
4042 const void *paths,
4043 GLuint pathBase,
4044 GLint reference,
4045 GLuint mask,
4046 GLenum transformType,
4047 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004048{
4049 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4050 transformType, transformValues))
4051 return false;
4052
4053 // no more validation here.
4054
4055 return true;
4056}
4057
Jamie Madill007530e2017-12-28 14:27:04 -05004058bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
4059 GLsizei numPaths,
4060 GLenum pathNameType,
4061 const void *paths,
4062 GLuint pathBase,
4063 GLenum fillMode,
4064 GLuint mask,
4065 GLenum coverMode,
4066 GLenum transformType,
4067 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004068{
4069 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4070 transformType, transformValues))
4071 return false;
4072
4073 switch (coverMode)
4074 {
4075 case GL_CONVEX_HULL_CHROMIUM:
4076 case GL_BOUNDING_BOX_CHROMIUM:
4077 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4078 break;
4079 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004080 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004081 return false;
4082 }
4083
4084 switch (fillMode)
4085 {
4086 case GL_COUNT_UP_CHROMIUM:
4087 case GL_COUNT_DOWN_CHROMIUM:
4088 break;
4089 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004090 context->validationError(GL_INVALID_ENUM, kInvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004091 return false;
4092 }
4093 if (!isPow2(mask + 1))
4094 {
Jamie Madille0472f32018-11-27 16:32:45 -05004095 context->validationError(GL_INVALID_VALUE, kInvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03004096 return false;
4097 }
4098
4099 return true;
4100}
4101
Jamie Madill007530e2017-12-28 14:27:04 -05004102bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
4103 GLsizei numPaths,
4104 GLenum pathNameType,
4105 const void *paths,
4106 GLuint pathBase,
4107 GLint reference,
4108 GLuint mask,
4109 GLenum coverMode,
4110 GLenum transformType,
4111 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03004112{
4113 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
4114 transformType, transformValues))
4115 return false;
4116
4117 switch (coverMode)
4118 {
4119 case GL_CONVEX_HULL_CHROMIUM:
4120 case GL_BOUNDING_BOX_CHROMIUM:
4121 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
4122 break;
4123 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004124 context->validationError(GL_INVALID_ENUM, kInvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03004125 return false;
4126 }
4127
4128 return true;
4129}
4130
Jamie Madill007530e2017-12-28 14:27:04 -05004131bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
4132 GLuint program,
4133 GLint location,
4134 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004135{
4136 if (!context->getExtensions().pathRendering)
4137 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004138 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004139 return false;
4140 }
4141
4142 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
4143 if (location >= MaxLocation)
4144 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004145 context->validationError(GL_INVALID_VALUE, kInvalidVaryingLocation);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004146 return false;
4147 }
4148
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004149 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004150 if (!programObject)
4151 {
Jamie Madille0472f32018-11-27 16:32:45 -05004152 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004153 return false;
4154 }
4155
4156 if (!name)
4157 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004158 context->validationError(GL_INVALID_VALUE, kMissingName);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004159 return false;
4160 }
4161
4162 if (angle::BeginsWith(name, "gl_"))
4163 {
Jamie Madille0472f32018-11-27 16:32:45 -05004164 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004165 return false;
4166 }
4167
4168 return true;
4169}
4170
Jamie Madill007530e2017-12-28 14:27:04 -05004171bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
4172 GLuint program,
4173 GLint location,
4174 GLenum genMode,
4175 GLint components,
4176 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03004177{
4178 if (!context->getExtensions().pathRendering)
4179 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004180 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004181 return false;
4182 }
4183
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004184 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004185 if (!programObject || programObject->isFlaggedForDeletion())
4186 {
Jamie Madille0472f32018-11-27 16:32:45 -05004187 context->validationError(GL_INVALID_OPERATION, kProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004188 return false;
4189 }
4190
4191 if (!programObject->isLinked())
4192 {
Jamie Madille0472f32018-11-27 16:32:45 -05004193 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004194 return false;
4195 }
4196
4197 switch (genMode)
4198 {
4199 case GL_NONE:
4200 if (components != 0)
4201 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004202 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004203 return false;
4204 }
4205 break;
4206
4207 case GL_OBJECT_LINEAR_CHROMIUM:
4208 case GL_EYE_LINEAR_CHROMIUM:
4209 case GL_CONSTANT_CHROMIUM:
4210 if (components < 1 || components > 4)
4211 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004212 context->validationError(GL_INVALID_VALUE, kInvalidComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004213 return false;
4214 }
4215 if (!coeffs)
4216 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004217 context->validationError(GL_INVALID_VALUE, kInvalidPathCoefficientsArray);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004218 return false;
4219 }
4220 break;
4221
4222 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004223 context->validationError(GL_INVALID_ENUM, kInvalidPathGenMode);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004224 return false;
4225 }
4226
4227 // If the location is -1 then the command is silently ignored
4228 // and no further validation is needed.
4229 if (location == -1)
4230 return true;
4231
jchen103fd614d2018-08-13 12:21:58 +08004232 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004233
4234 if (!binding.valid)
4235 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004236 context->validationError(GL_INVALID_OPERATION, kInvalidFragmentInputBinding);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004237 return false;
4238 }
4239
4240 if (binding.type != GL_NONE)
4241 {
4242 GLint expectedComponents = 0;
4243 switch (binding.type)
4244 {
4245 case GL_FLOAT:
4246 expectedComponents = 1;
4247 break;
4248 case GL_FLOAT_VEC2:
4249 expectedComponents = 2;
4250 break;
4251 case GL_FLOAT_VEC3:
4252 expectedComponents = 3;
4253 break;
4254 case GL_FLOAT_VEC4:
4255 expectedComponents = 4;
4256 break;
4257 default:
Jamie Madillc3e37312018-11-30 15:25:39 -05004258 context->validationError(GL_INVALID_OPERATION, kFragmentInputTypeNotFloatingPoint);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004259 return false;
4260 }
4261 if (expectedComponents != components && genMode != GL_NONE)
4262 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004263 context->validationError(GL_INVALID_OPERATION, kInvalidPathComponents);
Sami Väisänen46eaa942016-06-29 10:26:37 +03004264 return false;
4265 }
4266 }
4267 return true;
4268}
4269
Geoff Lang97073d12016-04-20 10:42:34 -07004270bool ValidateCopyTextureCHROMIUM(Context *context,
4271 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004272 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004273 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004274 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004275 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004276 GLint internalFormat,
4277 GLenum destType,
4278 GLboolean unpackFlipY,
4279 GLboolean unpackPremultiplyAlpha,
4280 GLboolean unpackUnmultiplyAlpha)
4281{
4282 if (!context->getExtensions().copyTexture)
4283 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004284 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004285 return false;
4286 }
4287
Geoff Lang4f0e0032017-05-01 16:04:35 -04004288 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004289 if (source == nullptr)
4290 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004291 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004292 return false;
4293 }
4294
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004295 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004296 {
Jamie Madille0472f32018-11-27 16:32:45 -05004297 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004298 return false;
4299 }
4300
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004301 TextureType sourceType = source->getType();
4302 ASSERT(sourceType != TextureType::CubeMap);
4303 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004304
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004305 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004306 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004307 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004308 return false;
4309 }
4310
Geoff Lang4f0e0032017-05-01 16:04:35 -04004311 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4312 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4313 if (sourceWidth == 0 || sourceHeight == 0)
4314 {
Jamie Madille0472f32018-11-27 16:32:45 -05004315 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004316 return false;
4317 }
4318
4319 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4320 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004321 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004322 context->validationError(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004323 return false;
4324 }
4325
Geoff Lang63458a32017-10-30 15:16:53 -04004326 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4327 {
Jamie Madille0472f32018-11-27 16:32:45 -05004328 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004329 return false;
4330 }
4331
Geoff Lang4f0e0032017-05-01 16:04:35 -04004332 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004333 if (dest == nullptr)
4334 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004335 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004336 return false;
4337 }
4338
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004339 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004340 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004341 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004342 return false;
4343 }
4344
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004345 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004346 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004347 {
Jamie Madille0472f32018-11-27 16:32:45 -05004348 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004349 return false;
4350 }
4351
Geoff Lang97073d12016-04-20 10:42:34 -07004352 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4353 {
Geoff Lang97073d12016-04-20 10:42:34 -07004354 return false;
4355 }
4356
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004357 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004358 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004359 context->validationError(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004360 return false;
4361 }
4362
Geoff Lang97073d12016-04-20 10:42:34 -07004363 if (dest->getImmutableFormat())
4364 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004365 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang97073d12016-04-20 10:42:34 -07004366 return false;
4367 }
4368
4369 return true;
4370}
4371
4372bool ValidateCopySubTextureCHROMIUM(Context *context,
4373 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004374 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004375 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004376 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004377 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004378 GLint xoffset,
4379 GLint yoffset,
4380 GLint x,
4381 GLint y,
4382 GLsizei width,
4383 GLsizei height,
4384 GLboolean unpackFlipY,
4385 GLboolean unpackPremultiplyAlpha,
4386 GLboolean unpackUnmultiplyAlpha)
4387{
4388 if (!context->getExtensions().copyTexture)
4389 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004390 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang97073d12016-04-20 10:42:34 -07004391 return false;
4392 }
4393
Geoff Lang4f0e0032017-05-01 16:04:35 -04004394 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004395 if (source == nullptr)
4396 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004397 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004398 return false;
4399 }
4400
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004401 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004402 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004403 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004404 return false;
4405 }
4406
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004407 TextureType sourceType = source->getType();
4408 ASSERT(sourceType != TextureType::CubeMap);
4409 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004410
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004411 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004412 {
Jamie Madille0472f32018-11-27 16:32:45 -05004413 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004414 return false;
4415 }
4416
4417 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4418 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004419 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004420 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004421 return false;
4422 }
4423
4424 if (x < 0 || y < 0)
4425 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004426 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004427 return false;
4428 }
4429
4430 if (width < 0 || height < 0)
4431 {
Jamie Madille0472f32018-11-27 16:32:45 -05004432 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004433 return false;
4434 }
4435
Geoff Lang4f0e0032017-05-01 16:04:35 -04004436 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4437 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004438 {
Jamie Madille0472f32018-11-27 16:32:45 -05004439 context->validationError(GL_INVALID_VALUE, kSourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004440 return false;
4441 }
4442
Geoff Lang4f0e0032017-05-01 16:04:35 -04004443 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4444 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004445 {
Jamie Madille0472f32018-11-27 16:32:45 -05004446 context->validationError(GL_INVALID_OPERATION, kInvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004447 return false;
4448 }
4449
Geoff Lang63458a32017-10-30 15:16:53 -04004450 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4451 {
Jamie Madille0472f32018-11-27 16:32:45 -05004452 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Geoff Lang63458a32017-10-30 15:16:53 -04004453 return false;
4454 }
4455
Geoff Lang4f0e0032017-05-01 16:04:35 -04004456 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004457 if (dest == nullptr)
4458 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004459 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang97073d12016-04-20 10:42:34 -07004460 return false;
4461 }
4462
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004463 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004464 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004465 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang97073d12016-04-20 10:42:34 -07004466 return false;
4467 }
4468
Brandon Jones28783792018-03-05 09:37:32 -08004469 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4470 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004471 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004472 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Geoff Lang97073d12016-04-20 10:42:34 -07004473 return false;
4474 }
4475
Geoff Lang4f0e0032017-05-01 16:04:35 -04004476 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4477 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004478 context->validationError(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004479 return false;
4480 }
4481
4482 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4483 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004484 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004485 context->validationError(GL_INVALID_OPERATION, kInvalidFormatCombination);
Geoff Lang97073d12016-04-20 10:42:34 -07004486 return false;
4487 }
4488
4489 if (xoffset < 0 || yoffset < 0)
4490 {
Jamie Madille0472f32018-11-27 16:32:45 -05004491 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004492 return false;
4493 }
4494
Geoff Lang4f0e0032017-05-01 16:04:35 -04004495 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4496 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004497 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004498 context->validationError(GL_INVALID_VALUE, kOffsetOverflow);
Geoff Lang97073d12016-04-20 10:42:34 -07004499 return false;
4500 }
4501
4502 return true;
4503}
4504
Geoff Lang47110bf2016-04-20 11:13:22 -07004505bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4506{
4507 if (!context->getExtensions().copyCompressedTexture)
4508 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004509 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Lang47110bf2016-04-20 11:13:22 -07004510 return false;
4511 }
4512
4513 const gl::Texture *source = context->getTexture(sourceId);
4514 if (source == nullptr)
4515 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004516 context->validationError(GL_INVALID_VALUE, kInvalidSourceTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004517 return false;
4518 }
4519
Corentin Wallez99d492c2018-02-27 15:17:10 -05004520 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004521 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004522 context->validationError(GL_INVALID_VALUE, kInvalidSourceTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004523 return false;
4524 }
4525
Corentin Wallez99d492c2018-02-27 15:17:10 -05004526 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4527 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004528 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004529 context->validationError(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
Geoff Lang47110bf2016-04-20 11:13:22 -07004530 return false;
4531 }
4532
Corentin Wallez99d492c2018-02-27 15:17:10 -05004533 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004534 if (!sourceFormat.info->compressed)
4535 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004536 context->validationError(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
Geoff Lang47110bf2016-04-20 11:13:22 -07004537 return false;
4538 }
4539
4540 const gl::Texture *dest = context->getTexture(destId);
4541 if (dest == nullptr)
4542 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004543 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTexture);
Geoff Lang47110bf2016-04-20 11:13:22 -07004544 return false;
4545 }
4546
Corentin Wallez99d492c2018-02-27 15:17:10 -05004547 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004548 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004549 context->validationError(GL_INVALID_VALUE, kInvalidDestinationTextureType);
Geoff Lang47110bf2016-04-20 11:13:22 -07004550 return false;
4551 }
4552
4553 if (dest->getImmutableFormat())
4554 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004555 context->validationError(GL_INVALID_OPERATION, kDestinationImmutable);
Geoff Lang47110bf2016-04-20 11:13:22 -07004556 return false;
4557 }
4558
4559 return true;
4560}
4561
Jiawei Shao385b3e02018-03-21 09:43:28 +08004562bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004563{
4564 switch (type)
4565 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004566 case ShaderType::Vertex:
4567 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004568 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004569
Jiawei Shao385b3e02018-03-21 09:43:28 +08004570 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004571 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004572 {
Jamie Madille0472f32018-11-27 16:32:45 -05004573 context->validationError(GL_INVALID_ENUM, kES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004574 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004575 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004576 break;
4577
Jiawei Shao385b3e02018-03-21 09:43:28 +08004578 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004579 if (!context->getExtensions().geometryShader)
4580 {
Jamie Madille0472f32018-11-27 16:32:45 -05004581 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jiawei Shao89be29a2017-11-06 14:36:45 +08004582 return false;
4583 }
4584 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004585 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004586 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004587 return false;
4588 }
Jamie Madill29639852016-09-02 15:00:09 -04004589
4590 return true;
4591}
4592
Jamie Madill5b772312018-03-08 20:28:32 -05004593bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004594 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004595 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004596 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004597 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004598{
4599 if (size < 0)
4600 {
Jamie Madille0472f32018-11-27 16:32:45 -05004601 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004602 return false;
4603 }
4604
4605 switch (usage)
4606 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004607 case BufferUsage::StreamDraw:
4608 case BufferUsage::StaticDraw:
4609 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004610 break;
4611
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004612 case BufferUsage::StreamRead:
4613 case BufferUsage::StaticRead:
4614 case BufferUsage::DynamicRead:
4615 case BufferUsage::StreamCopy:
4616 case BufferUsage::StaticCopy:
4617 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004618 if (context->getClientMajorVersion() < 3)
4619 {
Jamie Madille0472f32018-11-27 16:32:45 -05004620 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004621 return false;
4622 }
4623 break;
4624
4625 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004626 context->validationError(GL_INVALID_ENUM, kInvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004627 return false;
4628 }
4629
Corentin Walleze4477002017-12-01 14:39:58 -05004630 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004631 {
Jamie Madille0472f32018-11-27 16:32:45 -05004632 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004633 return false;
4634 }
4635
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004636 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004637
4638 if (!buffer)
4639 {
Jamie Madille0472f32018-11-27 16:32:45 -05004640 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004641 return false;
4642 }
4643
James Darpiniane8a93c62018-01-04 18:02:24 -08004644 if (context->getExtensions().webglCompatibility &&
4645 buffer->isBoundForTransformFeedbackAndOtherUse())
4646 {
Jamie Madille0472f32018-11-27 16:32:45 -05004647 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004648 return false;
4649 }
4650
Jamie Madill29639852016-09-02 15:00:09 -04004651 return true;
4652}
4653
Jamie Madill5b772312018-03-08 20:28:32 -05004654bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004655 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004656 GLintptr offset,
4657 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004658 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004659{
Brandon Jones6cad5662017-06-14 13:25:13 -07004660 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004661 {
Jamie Madille0472f32018-11-27 16:32:45 -05004662 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Brandon Jones6cad5662017-06-14 13:25:13 -07004663 return false;
4664 }
4665
4666 if (offset < 0)
4667 {
Jamie Madille0472f32018-11-27 16:32:45 -05004668 context->validationError(GL_INVALID_VALUE, kNegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004669 return false;
4670 }
4671
Corentin Walleze4477002017-12-01 14:39:58 -05004672 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004673 {
Jamie Madille0472f32018-11-27 16:32:45 -05004674 context->validationError(GL_INVALID_ENUM, kInvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004675 return false;
4676 }
4677
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004678 Buffer *buffer = context->getState().getTargetBuffer(target);
Jamie Madill29639852016-09-02 15:00:09 -04004679
4680 if (!buffer)
4681 {
Jamie Madille0472f32018-11-27 16:32:45 -05004682 context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004683 return false;
4684 }
4685
4686 if (buffer->isMapped())
4687 {
Jamie Madille0472f32018-11-27 16:32:45 -05004688 context->validationError(GL_INVALID_OPERATION, kBufferMapped);
Jamie Madill29639852016-09-02 15:00:09 -04004689 return false;
4690 }
4691
James Darpiniane8a93c62018-01-04 18:02:24 -08004692 if (context->getExtensions().webglCompatibility &&
4693 buffer->isBoundForTransformFeedbackAndOtherUse())
4694 {
Jamie Madille0472f32018-11-27 16:32:45 -05004695 context->validationError(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
James Darpiniane8a93c62018-01-04 18:02:24 -08004696 return false;
4697 }
4698
Jamie Madill29639852016-09-02 15:00:09 -04004699 // Check for possible overflow of size + offset
4700 angle::CheckedNumeric<size_t> checkedSize(size);
4701 checkedSize += offset;
4702 if (!checkedSize.IsValid())
4703 {
Jamie Madille0472f32018-11-27 16:32:45 -05004704 context->validationError(GL_INVALID_VALUE, kParamOverflow);
Jamie Madill29639852016-09-02 15:00:09 -04004705 return false;
4706 }
4707
4708 if (size + offset > buffer->getSize())
4709 {
Jamie Madille0472f32018-11-27 16:32:45 -05004710 context->validationError(GL_INVALID_VALUE, kInsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004711 return false;
4712 }
4713
Martin Radev4c4c8e72016-08-04 12:25:34 +03004714 return true;
4715}
4716
Geoff Lang111a99e2017-10-17 10:58:41 -04004717bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004718{
Geoff Langc339c4e2016-11-29 10:37:36 -05004719 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004720 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004721 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Geoff Langc287ea62016-09-16 14:46:51 -04004722 return false;
4723 }
4724
Geoff Lang111a99e2017-10-17 10:58:41 -04004725 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004726 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004727 context->validationError(GL_INVALID_OPERATION, kExtensionNotRequestable);
Geoff Langc287ea62016-09-16 14:46:51 -04004728 return false;
4729 }
4730
4731 return true;
4732}
4733
Jamie Madill5b772312018-03-08 20:28:32 -05004734bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004735{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004736 if (context->getClientMajorVersion() < 2)
4737 {
4738 return ValidateMultitextureUnit(context, texture);
4739 }
4740
Jamie Madillef300b12016-10-07 15:12:09 -04004741 if (texture < GL_TEXTURE0 ||
4742 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4743 {
Jamie Madille0472f32018-11-27 16:32:45 -05004744 context->validationError(GL_INVALID_ENUM, kInvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004745 return false;
4746 }
4747
4748 return true;
4749}
4750
Jamie Madill5b772312018-03-08 20:28:32 -05004751bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004752{
4753 Program *programObject = GetValidProgram(context, program);
4754 if (!programObject)
4755 {
4756 return false;
4757 }
4758
4759 Shader *shaderObject = GetValidShader(context, shader);
4760 if (!shaderObject)
4761 {
4762 return false;
4763 }
4764
Jiawei Shao385b3e02018-03-21 09:43:28 +08004765 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004766 {
Jamie Madille0472f32018-11-27 16:32:45 -05004767 context->validationError(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
Jiawei Shao385b3e02018-03-21 09:43:28 +08004768 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004769 }
4770
4771 return true;
4772}
4773
Jamie Madill5b772312018-03-08 20:28:32 -05004774bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004775{
4776 if (index >= MAX_VERTEX_ATTRIBS)
4777 {
Jamie Madille0472f32018-11-27 16:32:45 -05004778 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004779 return false;
4780 }
4781
4782 if (strncmp(name, "gl_", 3) == 0)
4783 {
Jamie Madille0472f32018-11-27 16:32:45 -05004784 context->validationError(GL_INVALID_OPERATION, kNameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004785 return false;
4786 }
4787
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004788 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004789 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004790 const size_t length = strlen(name);
4791
4792 if (!IsValidESSLString(name, length))
4793 {
4794 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4795 // for shader-related entry points
Jamie Madille0472f32018-11-27 16:32:45 -05004796 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004797 return false;
4798 }
4799
4800 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4801 {
4802 return false;
4803 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004804 }
4805
Jamie Madill01a80ee2016-11-07 12:06:18 -05004806 return GetValidProgram(context, program) != nullptr;
4807}
4808
Jamie Madill5b772312018-03-08 20:28:32 -05004809bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004810{
Geoff Lange8afa902017-09-27 15:00:43 -04004811 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004812 {
Jamie Madille0472f32018-11-27 16:32:45 -05004813 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004814 return false;
4815 }
4816
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004817 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004818 !context->isFramebufferGenerated(framebuffer))
4819 {
Jamie Madille0472f32018-11-27 16:32:45 -05004820 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004821 return false;
4822 }
4823
4824 return true;
4825}
4826
Jamie Madill5b772312018-03-08 20:28:32 -05004827bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004828{
4829 if (target != GL_RENDERBUFFER)
4830 {
Jamie Madille0472f32018-11-27 16:32:45 -05004831 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004832 return false;
4833 }
4834
Jamie Madillc3dc5d42018-12-30 12:12:04 -05004835 if (!context->getState().isBindGeneratesResourceEnabled() &&
Jamie Madill01a80ee2016-11-07 12:06:18 -05004836 !context->isRenderbufferGenerated(renderbuffer))
4837 {
Jamie Madille0472f32018-11-27 16:32:45 -05004838 context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004839 return false;
4840 }
4841
4842 return true;
4843}
4844
Jamie Madill5b772312018-03-08 20:28:32 -05004845static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004846{
4847 switch (mode)
4848 {
4849 case GL_FUNC_ADD:
4850 case GL_FUNC_SUBTRACT:
4851 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004852 return true;
4853
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004854 case GL_MIN:
4855 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004856 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004857
4858 default:
4859 return false;
4860 }
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004869{
Geoff Lang50cac572017-09-26 17:37:43 -04004870 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004871 {
Jamie Madille0472f32018-11-27 16:32:45 -05004872 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004873 return false;
4874 }
4875
4876 return true;
4877}
4878
Jamie Madill5b772312018-03-08 20:28:32 -05004879bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004880{
Geoff Lang50cac572017-09-26 17:37:43 -04004881 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004882 {
Jamie Madille0472f32018-11-27 16:32:45 -05004883 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004884 return false;
4885 }
4886
Geoff Lang50cac572017-09-26 17:37:43 -04004887 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004888 {
Jamie Madille0472f32018-11-27 16:32:45 -05004889 context->validationError(GL_INVALID_ENUM, kInvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004890 return false;
4891 }
4892
4893 return true;
4894}
4895
Jamie Madill5b772312018-03-08 20:28:32 -05004896bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004897{
4898 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4899}
4900
Jamie Madill5b772312018-03-08 20:28:32 -05004901bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004902 GLenum srcRGB,
4903 GLenum dstRGB,
4904 GLenum srcAlpha,
4905 GLenum dstAlpha)
4906{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004907 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004908 {
Jamie Madille0472f32018-11-27 16:32:45 -05004909 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004910 return false;
4911 }
4912
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004913 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004914 {
Jamie Madille0472f32018-11-27 16:32:45 -05004915 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004916 return false;
4917 }
4918
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004919 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004920 {
Jamie Madille0472f32018-11-27 16:32:45 -05004921 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004922 return false;
4923 }
4924
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004925 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004926 {
Jamie Madille0472f32018-11-27 16:32:45 -05004927 context->validationError(GL_INVALID_ENUM, kInvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004928 return false;
4929 }
4930
Frank Henigman146e8a12017-03-02 23:22:37 -05004931 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4932 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004933 {
4934 bool constantColorUsed =
4935 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4936 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4937
4938 bool constantAlphaUsed =
4939 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4940 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4941
4942 if (constantColorUsed && constantAlphaUsed)
4943 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004944 if (context->getExtensions().webglCompatibility)
4945 {
Jamie Madillc3e37312018-11-30 15:25:39 -05004946 context->validationError(GL_INVALID_OPERATION, kInvalidConstantColor);
4947 return false;
Frank Henigman146e8a12017-03-02 23:22:37 -05004948 }
Jamie Madillc3e37312018-11-30 15:25:39 -05004949
4950 WARN() << kConstantColorAlphaLimitation;
4951 context->validationError(GL_INVALID_OPERATION, kConstantColorAlphaLimitation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004952 return false;
4953 }
4954 }
4955
4956 return true;
4957}
4958
Geoff Langc339c4e2016-11-29 10:37:36 -05004959bool ValidateGetString(Context *context, GLenum name)
4960{
4961 switch (name)
4962 {
4963 case GL_VENDOR:
4964 case GL_RENDERER:
4965 case GL_VERSION:
4966 case GL_SHADING_LANGUAGE_VERSION:
4967 case GL_EXTENSIONS:
4968 break;
4969
4970 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4971 if (!context->getExtensions().requestExtension)
4972 {
Jamie Madille0472f32018-11-27 16:32:45 -05004973 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004974 return false;
4975 }
4976 break;
4977
4978 default:
Jamie Madille0472f32018-11-27 16:32:45 -05004979 context->validationError(GL_INVALID_ENUM, kInvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004980 return false;
4981 }
4982
4983 return true;
4984}
4985
Jamie Madill5b772312018-03-08 20:28:32 -05004986bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004987{
4988 if (width <= 0.0f || isNaN(width))
4989 {
Jamie Madille0472f32018-11-27 16:32:45 -05004990 context->validationError(GL_INVALID_VALUE, kInvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004991 return false;
4992 }
4993
4994 return true;
4995}
4996
Jamie Madill5b772312018-03-08 20:28:32 -05004997bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004998{
4999 if (context->getExtensions().webglCompatibility && zNear > zFar)
5000 {
Jamie Madille0472f32018-11-27 16:32:45 -05005001 context->validationError(GL_INVALID_OPERATION, kInvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05005002 return false;
5003 }
5004
5005 return true;
5006}
5007
Jamie Madill5b772312018-03-08 20:28:32 -05005008bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005009 GLenum target,
5010 GLenum internalformat,
5011 GLsizei width,
5012 GLsizei height)
5013{
5014 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
5015 height);
5016}
5017
Jamie Madill5b772312018-03-08 20:28:32 -05005018bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05005019 GLenum target,
5020 GLsizei samples,
5021 GLenum internalformat,
5022 GLsizei width,
5023 GLsizei height)
5024{
5025 if (!context->getExtensions().framebufferMultisample)
5026 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005027 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madille8fb6402017-02-14 17:56:40 -05005028 return false;
5029 }
5030
5031 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
Jamie Madill610640f2018-11-21 17:28:41 -05005032 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
Jamie Madille8fb6402017-02-14 17:56:40 -05005033 // generated.
5034 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
5035 {
Jamie Madille0472f32018-11-27 16:32:45 -05005036 context->validationError(GL_INVALID_VALUE, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005037 return false;
5038 }
5039
5040 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
5041 // the specified storage. This is different than ES 3.0 in which a sample number higher
5042 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
5043 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
5044 if (context->getClientMajorVersion() >= 3)
5045 {
5046 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
5047 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
5048 {
Jamie Madille0472f32018-11-27 16:32:45 -05005049 context->validationError(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
Jamie Madille8fb6402017-02-14 17:56:40 -05005050 return false;
5051 }
5052 }
5053
5054 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
5055 width, height);
5056}
5057
Jamie Madill5b772312018-03-08 20:28:32 -05005058bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005059{
Geoff Lange8afa902017-09-27 15:00:43 -04005060 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005061 {
Jamie Madille0472f32018-11-27 16:32:45 -05005062 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005063 return false;
5064 }
5065
5066 return true;
5067}
5068
Jamie Madill5b772312018-03-08 20:28:32 -05005069bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005070{
5071 return true;
5072}
5073
Jamie Madill5b772312018-03-08 20:28:32 -05005074bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005075{
5076 return true;
5077}
5078
Jamie Madill5b772312018-03-08 20:28:32 -05005079bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005080{
5081 return true;
5082}
5083
Jamie Madill5b772312018-03-08 20:28:32 -05005084bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005085 GLboolean red,
5086 GLboolean green,
5087 GLboolean blue,
5088 GLboolean alpha)
5089{
5090 return true;
5091}
5092
Jamie Madill5b772312018-03-08 20:28:32 -05005093bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005094{
5095 return true;
5096}
5097
Jamie Madill5b772312018-03-08 20:28:32 -05005098bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099{
5100 return true;
5101}
5102
Jamie Madill5b772312018-03-08 20:28:32 -05005103bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005104{
5105 switch (mode)
5106 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04005107 case CullFaceMode::Front:
5108 case CullFaceMode::Back:
5109 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04005110 break;
5111
5112 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005113 context->validationError(GL_INVALID_ENUM, kInvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005114 return false;
5115 }
5116
5117 return true;
5118}
5119
Jamie Madill5b772312018-03-08 20:28:32 -05005120bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005121{
5122 if (program == 0)
5123 {
5124 return false;
5125 }
5126
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005127 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005128 {
5129 if (context->getShader(program))
5130 {
Jamie Madille0472f32018-11-27 16:32:45 -05005131 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005132 return false;
5133 }
5134 else
5135 {
Jamie Madille0472f32018-11-27 16:32:45 -05005136 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137 return false;
5138 }
5139 }
5140
5141 return true;
5142}
5143
Jamie Madill5b772312018-03-08 20:28:32 -05005144bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005145{
5146 if (shader == 0)
5147 {
5148 return false;
5149 }
5150
5151 if (!context->getShader(shader))
5152 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04005153 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04005154 {
Jamie Madille0472f32018-11-27 16:32:45 -05005155 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156 return false;
5157 }
5158 else
5159 {
Jamie Madille0472f32018-11-27 16:32:45 -05005160 context->validationError(GL_INVALID_VALUE, kExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 return false;
5162 }
5163 }
5164
5165 return true;
5166}
5167
Jamie Madill5b772312018-03-08 20:28:32 -05005168bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169{
5170 switch (func)
5171 {
5172 case GL_NEVER:
5173 case GL_ALWAYS:
5174 case GL_LESS:
5175 case GL_LEQUAL:
5176 case GL_EQUAL:
5177 case GL_GREATER:
5178 case GL_GEQUAL:
5179 case GL_NOTEQUAL:
5180 break;
5181
5182 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005183 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005184 return false;
5185 }
5186
5187 return true;
5188}
5189
Jamie Madill5b772312018-03-08 20:28:32 -05005190bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005191{
5192 return true;
5193}
5194
Jamie Madill5b772312018-03-08 20:28:32 -05005195bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005196{
5197 Program *programObject = GetValidProgram(context, program);
5198 if (!programObject)
5199 {
5200 return false;
5201 }
5202
5203 Shader *shaderObject = GetValidShader(context, shader);
5204 if (!shaderObject)
5205 {
5206 return false;
5207 }
5208
Jiawei Shao385b3e02018-03-21 09:43:28 +08005209 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005210 if (attachedShader != shaderObject)
5211 {
Jamie Madille0472f32018-11-27 16:32:45 -05005212 context->validationError(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005213 return false;
5214 }
5215
5216 return true;
5217}
5218
Jamie Madill5b772312018-03-08 20:28:32 -05005219bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005220{
5221 if (index >= MAX_VERTEX_ATTRIBS)
5222 {
Jamie Madille0472f32018-11-27 16:32:45 -05005223 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005224 return false;
5225 }
5226
5227 return true;
5228}
5229
Jamie Madill5b772312018-03-08 20:28:32 -05005230bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005231{
5232 if (index >= MAX_VERTEX_ATTRIBS)
5233 {
Jamie Madille0472f32018-11-27 16:32:45 -05005234 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005235 return false;
5236 }
5237
5238 return true;
5239}
5240
Jamie Madill5b772312018-03-08 20:28:32 -05005241bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005242{
5243 return true;
5244}
5245
Jamie Madill5b772312018-03-08 20:28:32 -05005246bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005247{
5248 return true;
5249}
5250
Jamie Madill5b772312018-03-08 20:28:32 -05005251bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252{
5253 switch (mode)
5254 {
5255 case GL_CW:
5256 case GL_CCW:
5257 break;
5258 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005259 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005260 return false;
5261 }
5262
5263 return true;
5264}
5265
Jamie Madill5b772312018-03-08 20:28:32 -05005266bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 GLuint program,
5268 GLuint index,
5269 GLsizei bufsize,
5270 GLsizei *length,
5271 GLint *size,
5272 GLenum *type,
5273 GLchar *name)
5274{
5275 if (bufsize < 0)
5276 {
Jamie Madille0472f32018-11-27 16:32:45 -05005277 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005278 return false;
5279 }
5280
5281 Program *programObject = GetValidProgram(context, program);
5282
5283 if (!programObject)
5284 {
5285 return false;
5286 }
5287
5288 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5289 {
Jamie Madille0472f32018-11-27 16:32:45 -05005290 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005291 return false;
5292 }
5293
5294 return true;
5295}
5296
Jamie Madill5b772312018-03-08 20:28:32 -05005297bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005298 GLuint program,
5299 GLuint index,
5300 GLsizei bufsize,
5301 GLsizei *length,
5302 GLint *size,
5303 GLenum *type,
5304 GLchar *name)
5305{
5306 if (bufsize < 0)
5307 {
Jamie Madille0472f32018-11-27 16:32:45 -05005308 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 return false;
5310 }
5311
5312 Program *programObject = GetValidProgram(context, program);
5313
5314 if (!programObject)
5315 {
5316 return false;
5317 }
5318
5319 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5320 {
Jamie Madille0472f32018-11-27 16:32:45 -05005321 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005322 return false;
5323 }
5324
5325 return true;
5326}
5327
Jamie Madill5b772312018-03-08 20:28:32 -05005328bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005329 GLuint program,
5330 GLsizei maxcount,
5331 GLsizei *count,
5332 GLuint *shaders)
5333{
5334 if (maxcount < 0)
5335 {
Jamie Madille0472f32018-11-27 16:32:45 -05005336 context->validationError(GL_INVALID_VALUE, kNegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337 return false;
5338 }
5339
5340 Program *programObject = GetValidProgram(context, program);
5341
5342 if (!programObject)
5343 {
5344 return false;
5345 }
5346
5347 return true;
5348}
5349
Jamie Madill5b772312018-03-08 20:28:32 -05005350bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005351{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005352 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5353 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005354 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005355 {
Jamie Madille0472f32018-11-27 16:32:45 -05005356 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005357 return false;
5358 }
5359
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360 Program *programObject = GetValidProgram(context, program);
5361
5362 if (!programObject)
5363 {
Jamie Madille0472f32018-11-27 16:32:45 -05005364 context->validationError(GL_INVALID_OPERATION, kProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005365 return false;
5366 }
5367
5368 if (!programObject->isLinked())
5369 {
Jamie Madille0472f32018-11-27 16:32:45 -05005370 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005371 return false;
5372 }
5373
5374 return true;
5375}
5376
Jamie Madill5b772312018-03-08 20:28:32 -05005377bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378{
5379 GLenum nativeType;
5380 unsigned int numParams = 0;
5381 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5382}
5383
Jamie Madill5b772312018-03-08 20:28:32 -05005384bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385{
5386 return true;
5387}
5388
Jamie Madill5b772312018-03-08 20:28:32 -05005389bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390{
5391 GLenum nativeType;
5392 unsigned int numParams = 0;
5393 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 GLenum nativeType;
5399 unsigned int numParams = 0;
5400 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5401}
5402
Jamie Madill5b772312018-03-08 20:28:32 -05005403bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005404 GLuint program,
5405 GLsizei bufsize,
5406 GLsizei *length,
5407 GLchar *infolog)
5408{
5409 if (bufsize < 0)
5410 {
Jamie Madille0472f32018-11-27 16:32:45 -05005411 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005412 return false;
5413 }
5414
5415 Program *programObject = GetValidProgram(context, program);
5416 if (!programObject)
5417 {
5418 return false;
5419 }
5420
5421 return true;
5422}
5423
Jamie Madill5b772312018-03-08 20:28:32 -05005424bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 GLuint shader,
5426 GLsizei bufsize,
5427 GLsizei *length,
5428 GLchar *infolog)
5429{
5430 if (bufsize < 0)
5431 {
Jamie Madille0472f32018-11-27 16:32:45 -05005432 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005433 return false;
5434 }
5435
5436 Shader *shaderObject = GetValidShader(context, shader);
5437 if (!shaderObject)
5438 {
5439 return false;
5440 }
5441
5442 return true;
5443}
5444
Jamie Madill5b772312018-03-08 20:28:32 -05005445bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005446 GLenum shadertype,
5447 GLenum precisiontype,
5448 GLint *range,
5449 GLint *precision)
5450{
5451 switch (shadertype)
5452 {
5453 case GL_VERTEX_SHADER:
5454 case GL_FRAGMENT_SHADER:
5455 break;
5456 case GL_COMPUTE_SHADER:
Jamie Madillc3e37312018-11-30 15:25:39 -05005457 context->validationError(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005458 return false;
5459 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005460 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005461 return false;
5462 }
5463
5464 switch (precisiontype)
5465 {
5466 case GL_LOW_FLOAT:
5467 case GL_MEDIUM_FLOAT:
5468 case GL_HIGH_FLOAT:
5469 case GL_LOW_INT:
5470 case GL_MEDIUM_INT:
5471 case GL_HIGH_INT:
5472 break;
5473
5474 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005475 context->validationError(GL_INVALID_ENUM, kInvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005476 return false;
5477 }
5478
5479 return true;
5480}
5481
Jamie Madill5b772312018-03-08 20:28:32 -05005482bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005483 GLuint shader,
5484 GLsizei bufsize,
5485 GLsizei *length,
5486 GLchar *source)
5487{
5488 if (bufsize < 0)
5489 {
Jamie Madille0472f32018-11-27 16:32:45 -05005490 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005491 return false;
5492 }
5493
5494 Shader *shaderObject = GetValidShader(context, shader);
5495 if (!shaderObject)
5496 {
5497 return false;
5498 }
5499
5500 return true;
5501}
5502
Jamie Madill5b772312018-03-08 20:28:32 -05005503bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504{
5505 if (strstr(name, "gl_") == name)
5506 {
5507 return false;
5508 }
5509
Geoff Langfc32e8b2017-05-31 14:16:59 -04005510 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5511 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005512 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005513 {
Jamie Madille0472f32018-11-27 16:32:45 -05005514 context->validationError(GL_INVALID_VALUE, kInvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005515 return false;
5516 }
5517
Jamie Madillc1d770e2017-04-13 17:31:24 -04005518 Program *programObject = GetValidProgram(context, program);
5519
5520 if (!programObject)
5521 {
5522 return false;
5523 }
5524
5525 if (!programObject->isLinked())
5526 {
Jamie Madille0472f32018-11-27 16:32:45 -05005527 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005528 return false;
5529 }
5530
5531 return true;
5532}
5533
Jamie Madill5b772312018-03-08 20:28:32 -05005534bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005535{
5536 switch (mode)
5537 {
5538 case GL_FASTEST:
5539 case GL_NICEST:
5540 case GL_DONT_CARE:
5541 break;
5542
5543 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005544 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005545 return false;
5546 }
5547
5548 switch (target)
5549 {
5550 case GL_GENERATE_MIPMAP_HINT:
5551 break;
5552
Geoff Lange7bd2182017-06-16 16:13:13 -04005553 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5554 if (context->getClientVersion() < ES_3_0 &&
5555 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005556 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005557 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 return false;
5559 }
5560 break;
5561
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005562 case GL_PERSPECTIVE_CORRECTION_HINT:
5563 case GL_POINT_SMOOTH_HINT:
5564 case GL_LINE_SMOOTH_HINT:
5565 case GL_FOG_HINT:
5566 if (context->getClientMajorVersion() >= 2)
5567 {
Jamie Madille0472f32018-11-27 16:32:45 -05005568 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005569 return false;
5570 }
5571 break;
5572
Jamie Madillc1d770e2017-04-13 17:31:24 -04005573 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005574 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005575 return false;
5576 }
5577
5578 return true;
5579}
5580
Jamie Madill5b772312018-03-08 20:28:32 -05005581bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005582{
5583 return true;
5584}
5585
Jamie Madill5b772312018-03-08 20:28:32 -05005586bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005587{
5588 return true;
5589}
5590
Jamie Madill5b772312018-03-08 20:28:32 -05005591bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592{
5593 return true;
5594}
5595
Jamie Madill5b772312018-03-08 20:28:32 -05005596bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005597{
5598 return true;
5599}
5600
Jamie Madill5b772312018-03-08 20:28:32 -05005601bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602{
5603 return true;
5604}
5605
Jamie Madill5b772312018-03-08 20:28:32 -05005606bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005607{
5608 return true;
5609}
5610
Jamie Madill5b772312018-03-08 20:28:32 -05005611bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005612{
5613 if (context->getClientMajorVersion() < 3)
5614 {
5615 switch (pname)
5616 {
5617 case GL_UNPACK_IMAGE_HEIGHT:
5618 case GL_UNPACK_SKIP_IMAGES:
Jamie Madille0472f32018-11-27 16:32:45 -05005619 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005620 return false;
5621
5622 case GL_UNPACK_ROW_LENGTH:
5623 case GL_UNPACK_SKIP_ROWS:
5624 case GL_UNPACK_SKIP_PIXELS:
5625 if (!context->getExtensions().unpackSubimage)
5626 {
Jamie Madille0472f32018-11-27 16:32:45 -05005627 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005628 return false;
5629 }
5630 break;
5631
5632 case GL_PACK_ROW_LENGTH:
5633 case GL_PACK_SKIP_ROWS:
5634 case GL_PACK_SKIP_PIXELS:
5635 if (!context->getExtensions().packSubimage)
5636 {
Jamie Madille0472f32018-11-27 16:32:45 -05005637 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638 return false;
5639 }
5640 break;
5641 }
5642 }
5643
5644 if (param < 0)
5645 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005646 context->validationError(GL_INVALID_VALUE, kNegativeParam);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005647 return false;
5648 }
5649
5650 switch (pname)
5651 {
5652 case GL_UNPACK_ALIGNMENT:
5653 if (param != 1 && param != 2 && param != 4 && param != 8)
5654 {
Jamie Madille0472f32018-11-27 16:32:45 -05005655 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656 return false;
5657 }
5658 break;
5659
5660 case GL_PACK_ALIGNMENT:
5661 if (param != 1 && param != 2 && param != 4 && param != 8)
5662 {
Jamie Madille0472f32018-11-27 16:32:45 -05005663 context->validationError(GL_INVALID_VALUE, kInvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005664 return false;
5665 }
5666 break;
5667
5668 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005669 if (!context->getExtensions().packReverseRowOrder)
5670 {
Jamie Madille0472f32018-11-27 16:32:45 -05005671 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Geoff Lang000dab82017-09-27 14:27:07 -04005672 }
5673 break;
5674
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675 case GL_UNPACK_ROW_LENGTH:
5676 case GL_UNPACK_IMAGE_HEIGHT:
5677 case GL_UNPACK_SKIP_IMAGES:
5678 case GL_UNPACK_SKIP_ROWS:
5679 case GL_UNPACK_SKIP_PIXELS:
5680 case GL_PACK_ROW_LENGTH:
5681 case GL_PACK_SKIP_ROWS:
5682 case GL_PACK_SKIP_PIXELS:
5683 break;
5684
5685 default:
Jamie Madille0472f32018-11-27 16:32:45 -05005686 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005687 return false;
5688 }
5689
5690 return true;
5691}
5692
Jamie Madill5b772312018-03-08 20:28:32 -05005693bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005694{
5695 return true;
5696}
5697
Jamie Madill5b772312018-03-08 20:28:32 -05005698bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005699{
5700 return true;
5701}
5702
Jamie Madill5b772312018-03-08 20:28:32 -05005703bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005704{
5705 return true;
5706}
5707
Jamie Madill5b772312018-03-08 20:28:32 -05005708bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005709{
5710 if (width < 0 || height < 0)
5711 {
Jamie Madille0472f32018-11-27 16:32:45 -05005712 context->validationError(GL_INVALID_VALUE, kNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713 return false;
5714 }
5715
5716 return true;
5717}
5718
Jamie Madill5b772312018-03-08 20:28:32 -05005719bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005720 GLsizei n,
5721 const GLuint *shaders,
5722 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005723 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724 GLsizei length)
5725{
5726 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5727 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5728 shaderBinaryFormats.end())
5729 {
Jamie Madillc3e37312018-11-30 15:25:39 -05005730 context->validationError(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005731 return false;
5732 }
5733
5734 return true;
5735}
5736
Jamie Madill5b772312018-03-08 20:28:32 -05005737bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005738 GLuint shader,
5739 GLsizei count,
5740 const GLchar *const *string,
5741 const GLint *length)
5742{
5743 if (count < 0)
5744 {
Jamie Madille0472f32018-11-27 16:32:45 -05005745 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005746 return false;
5747 }
5748
Geoff Langfc32e8b2017-05-31 14:16:59 -04005749 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5750 // shader-related entry points
5751 if (context->getExtensions().webglCompatibility)
5752 {
5753 for (GLsizei i = 0; i < count; i++)
5754 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005755 size_t len =
5756 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005757
5758 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005759 if (!IsValidESSLShaderSourceString(string[i], len,
5760 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005761 {
Jamie Madille0472f32018-11-27 16:32:45 -05005762 context->validationError(GL_INVALID_VALUE, kShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005763 return false;
5764 }
5765 }
5766 }
5767
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768 Shader *shaderObject = GetValidShader(context, shader);
5769 if (!shaderObject)
5770 {
5771 return false;
5772 }
5773
5774 return true;
5775}
5776
Jamie Madill5b772312018-03-08 20:28:32 -05005777bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005778{
5779 if (!IsValidStencilFunc(func))
5780 {
Jamie Madille0472f32018-11-27 16:32:45 -05005781 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005782 return false;
5783 }
5784
5785 return true;
5786}
5787
Jamie Madill5b772312018-03-08 20:28:32 -05005788bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005789{
5790 if (!IsValidStencilFace(face))
5791 {
Jamie Madille0472f32018-11-27 16:32:45 -05005792 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005793 return false;
5794 }
5795
5796 if (!IsValidStencilFunc(func))
5797 {
Jamie Madille0472f32018-11-27 16:32:45 -05005798 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799 return false;
5800 }
5801
5802 return true;
5803}
5804
Jamie Madill5b772312018-03-08 20:28:32 -05005805bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005806{
5807 return true;
5808}
5809
Jamie Madill5b772312018-03-08 20:28:32 -05005810bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005811{
5812 if (!IsValidStencilFace(face))
5813 {
Jamie Madille0472f32018-11-27 16:32:45 -05005814 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005815 return false;
5816 }
5817
5818 return true;
5819}
5820
Jamie Madill5b772312018-03-08 20:28:32 -05005821bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005822{
5823 if (!IsValidStencilOp(fail))
5824 {
Jamie Madille0472f32018-11-27 16:32:45 -05005825 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005826 return false;
5827 }
5828
5829 if (!IsValidStencilOp(zfail))
5830 {
Jamie Madille0472f32018-11-27 16:32:45 -05005831 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005832 return false;
5833 }
5834
5835 if (!IsValidStencilOp(zpass))
5836 {
Jamie Madille0472f32018-11-27 16:32:45 -05005837 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005838 return false;
5839 }
5840
5841 return true;
5842}
5843
Jamie Madill5b772312018-03-08 20:28:32 -05005844bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005845 GLenum face,
5846 GLenum fail,
5847 GLenum zfail,
5848 GLenum zpass)
5849{
5850 if (!IsValidStencilFace(face))
5851 {
Jamie Madille0472f32018-11-27 16:32:45 -05005852 context->validationError(GL_INVALID_ENUM, kInvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005853 return false;
5854 }
5855
5856 return ValidateStencilOp(context, fail, zfail, zpass);
5857}
5858
Jamie Madill5b772312018-03-08 20:28:32 -05005859bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005860{
5861 return ValidateUniform(context, GL_FLOAT, location, 1);
5862}
5863
Jamie Madill5b772312018-03-08 20:28:32 -05005864bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005865{
5866 return ValidateUniform(context, GL_FLOAT, location, count);
5867}
5868
Jamie Madill5b772312018-03-08 20:28:32 -05005869bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005870{
5871 return ValidateUniform1iv(context, location, 1, &x);
5872}
5873
Jamie Madill5b772312018-03-08 20:28:32 -05005874bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005875{
5876 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5877}
5878
Jamie Madill5b772312018-03-08 20:28:32 -05005879bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005880{
5881 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5882}
5883
Jamie Madill5b772312018-03-08 20:28:32 -05005884bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005885{
5886 return ValidateUniform(context, GL_INT_VEC2, location, count);
5887}
5888
Jamie Madill5b772312018-03-08 20:28:32 -05005889bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005890{
5891 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5892}
5893
Jamie Madill5b772312018-03-08 20:28:32 -05005894bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005895{
5896 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5897}
5898
Jamie Madill5b772312018-03-08 20:28:32 -05005899bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005900{
5901 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5902}
5903
Jamie Madill5b772312018-03-08 20:28:32 -05005904bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005905{
5906 return ValidateUniform(context, GL_INT_VEC3, location, count);
5907}
5908
Jamie Madill5b772312018-03-08 20:28:32 -05005909bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005910{
5911 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5912}
5913
Jamie Madill5b772312018-03-08 20:28:32 -05005914bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005915{
5916 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5917}
5918
Jamie Madill5b772312018-03-08 20:28:32 -05005919bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005920{
5921 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5922}
5923
Jamie Madill5b772312018-03-08 20:28:32 -05005924bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005925{
5926 return ValidateUniform(context, GL_INT_VEC4, location, count);
5927}
5928
Jamie Madill5b772312018-03-08 20:28:32 -05005929bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005930 GLint location,
5931 GLsizei count,
5932 GLboolean transpose,
5933 const GLfloat *value)
5934{
5935 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5936}
5937
Jamie Madill5b772312018-03-08 20:28:32 -05005938bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005939 GLint location,
5940 GLsizei count,
5941 GLboolean transpose,
5942 const GLfloat *value)
5943{
5944 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5945}
5946
Jamie Madill5b772312018-03-08 20:28:32 -05005947bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005948 GLint location,
5949 GLsizei count,
5950 GLboolean transpose,
5951 const GLfloat *value)
5952{
5953 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5954}
5955
Jamie Madill5b772312018-03-08 20:28:32 -05005956bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005957{
5958 Program *programObject = GetValidProgram(context, program);
5959
5960 if (!programObject)
5961 {
5962 return false;
5963 }
5964
5965 return true;
5966}
5967
Jamie Madill5b772312018-03-08 20:28:32 -05005968bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005969{
5970 return ValidateVertexAttribIndex(context, index);
5971}
5972
Jamie Madill5b772312018-03-08 20:28:32 -05005973bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005974{
5975 return ValidateVertexAttribIndex(context, index);
5976}
5977
Jamie Madill5b772312018-03-08 20:28:32 -05005978bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005979{
5980 return ValidateVertexAttribIndex(context, index);
5981}
5982
Jamie Madill5b772312018-03-08 20:28:32 -05005983bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005984{
5985 return ValidateVertexAttribIndex(context, index);
5986}
5987
Jamie Madill5b772312018-03-08 20:28:32 -05005988bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005989{
5990 return ValidateVertexAttribIndex(context, index);
5991}
5992
Jamie Madill5b772312018-03-08 20:28:32 -05005993bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005994{
5995 return ValidateVertexAttribIndex(context, index);
5996}
5997
Jamie Madill5b772312018-03-08 20:28:32 -05005998bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005999 GLuint index,
6000 GLfloat x,
6001 GLfloat y,
6002 GLfloat z,
6003 GLfloat w)
6004{
6005 return ValidateVertexAttribIndex(context, index);
6006}
6007
Jamie Madill5b772312018-03-08 20:28:32 -05006008bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006009{
6010 return ValidateVertexAttribIndex(context, index);
6011}
6012
Jamie Madill5b772312018-03-08 20:28:32 -05006013bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04006014{
6015 if (width < 0 || height < 0)
6016 {
Jamie Madille0472f32018-11-27 16:32:45 -05006017 context->validationError(GL_INVALID_VALUE, kViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04006018 return false;
6019 }
6020
6021 return true;
6022}
6023
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08006024bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 GLenum target,
6026 GLenum attachment,
6027 GLenum pname,
6028 GLint *params)
6029{
6030 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
6031 nullptr);
6032}
6033
Jamie Madill5b772312018-03-08 20:28:32 -05006034bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006035{
6036 return ValidateGetProgramivBase(context, program, pname, nullptr);
6037}
6038
Jamie Madill5b772312018-03-08 20:28:32 -05006039bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006040 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 GLint level,
6042 GLenum internalformat,
6043 GLint x,
6044 GLint y,
6045 GLsizei width,
6046 GLsizei height,
6047 GLint border)
6048{
6049 if (context->getClientMajorVersion() < 3)
6050 {
6051 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
6052 0, x, y, width, height, border);
6053 }
6054
6055 ASSERT(context->getClientMajorVersion() == 3);
6056 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
6057 0, x, y, width, height, border);
6058}
6059
6060bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006061 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006062 GLint level,
6063 GLint xoffset,
6064 GLint yoffset,
6065 GLint x,
6066 GLint y,
6067 GLsizei width,
6068 GLsizei height)
6069{
6070 if (context->getClientMajorVersion() < 3)
6071 {
6072 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
6073 yoffset, x, y, width, height, 0);
6074 }
6075
6076 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
6077 yoffset, 0, x, y, width, height, 0);
6078}
6079
6080bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
6081{
6082 return ValidateGenOrDelete(context, n);
6083}
6084
6085bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
6086{
6087 return ValidateGenOrDelete(context, n);
6088}
6089
6090bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
6091{
6092 return ValidateGenOrDelete(context, n);
6093}
6094
6095bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
6096{
6097 return ValidateGenOrDelete(context, n);
6098}
6099
6100bool ValidateDisable(Context *context, GLenum cap)
6101{
6102 if (!ValidCap(context, cap, false))
6103 {
Jamie Madille0472f32018-11-27 16:32:45 -05006104 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006105 return false;
6106 }
6107
6108 return true;
6109}
6110
6111bool ValidateEnable(Context *context, GLenum cap)
6112{
6113 if (!ValidCap(context, cap, false))
6114 {
Jamie Madille0472f32018-11-27 16:32:45 -05006115 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006116 return false;
6117 }
6118
6119 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
6120 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
6121 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006122 context->validationError(GL_INVALID_OPERATION, kNoSampleAlphaToCoveragesLimitation);
Jamie Madillbe849e42017-05-02 15:49:00 -04006123
6124 // We also output an error message to the debugger window if tracing is active, so that
6125 // developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006126 ERR() << kNoSampleAlphaToCoveragesLimitation;
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
6129
6130 return true;
6131}
6132
6133bool ValidateFramebufferRenderbuffer(Context *context,
6134 GLenum target,
6135 GLenum attachment,
6136 GLenum renderbuffertarget,
6137 GLuint renderbuffer)
6138{
Geoff Lange8afa902017-09-27 15:00:43 -04006139 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04006140 {
Jamie Madille0472f32018-11-27 16:32:45 -05006141 context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
Brandon Jones6cad5662017-06-14 13:25:13 -07006142 return false;
6143 }
6144
6145 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
6146 {
Jamie Madille0472f32018-11-27 16:32:45 -05006147 context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006148 return false;
6149 }
6150
6151 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
6152 renderbuffertarget, renderbuffer);
6153}
6154
6155bool ValidateFramebufferTexture2D(Context *context,
6156 GLenum target,
6157 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006158 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04006159 GLuint texture,
6160 GLint level)
6161{
6162 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
6163 // extension
6164 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
6165 level != 0)
6166 {
Jamie Madille0472f32018-11-27 16:32:45 -05006167 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006168 return false;
6169 }
6170
6171 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
6172 {
6173 return false;
6174 }
6175
6176 if (texture != 0)
6177 {
6178 gl::Texture *tex = context->getTexture(texture);
6179 ASSERT(tex);
6180
6181 const gl::Caps &caps = context->getCaps();
6182
6183 switch (textarget)
6184 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006185 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006186 {
6187 if (level > gl::log2(caps.max2DTextureSize))
6188 {
Jamie Madille0472f32018-11-27 16:32:45 -05006189 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006190 return false;
6191 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006192 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006193 {
Jamie Madille0472f32018-11-27 16:32:45 -05006194 context->validationError(GL_INVALID_OPERATION, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006195 return false;
6196 }
6197 }
6198 break;
6199
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006200 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006201 {
6202 if (level != 0)
6203 {
Jamie Madille0472f32018-11-27 16:32:45 -05006204 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006205 return false;
6206 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006207 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006208 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006209 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006210 return false;
6211 }
6212 }
6213 break;
6214
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006215 case TextureTarget::CubeMapNegativeX:
6216 case TextureTarget::CubeMapNegativeY:
6217 case TextureTarget::CubeMapNegativeZ:
6218 case TextureTarget::CubeMapPositiveX:
6219 case TextureTarget::CubeMapPositiveY:
6220 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006221 {
6222 if (level > gl::log2(caps.maxCubeMapTextureSize))
6223 {
Jamie Madille0472f32018-11-27 16:32:45 -05006224 context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04006225 return false;
6226 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006227 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006228 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006229 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006230 return false;
6231 }
6232 }
6233 break;
6234
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006235 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006236 {
Yizhou Jiang7818a852018-09-06 15:02:04 +08006237 if (context->getClientVersion() < ES_3_1 &&
6238 !context->getExtensions().textureMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006239 {
Jamie Madill610640f2018-11-21 17:28:41 -05006240 context->validationError(GL_INVALID_OPERATION,
Jamie Madille0472f32018-11-27 16:32:45 -05006241 kMultisampleTextureExtensionOrES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006242 return false;
6243 }
6244
6245 if (level != 0)
6246 {
Jamie Madille0472f32018-11-27 16:32:45 -05006247 context->validationError(GL_INVALID_VALUE, kLevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006248 return false;
6249 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006250 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006251 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006252 context->validationError(GL_INVALID_OPERATION, kTextureTargetMismatch);
Jamie Madillbe849e42017-05-02 15:49:00 -04006253 return false;
6254 }
6255 }
6256 break;
6257
6258 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006259 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006260 return false;
6261 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006262 }
6263
6264 return true;
6265}
6266
6267bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6268{
6269 return ValidateGenOrDelete(context, n);
6270}
6271
6272bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6273{
6274 return ValidateGenOrDelete(context, n);
6275}
6276
6277bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6278{
6279 return ValidateGenOrDelete(context, n);
6280}
6281
6282bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6283{
6284 return ValidateGenOrDelete(context, n);
6285}
6286
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006287bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006288{
6289 if (!ValidTextureTarget(context, target))
6290 {
Jamie Madille0472f32018-11-27 16:32:45 -05006291 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006292 return false;
6293 }
6294
Jamie Madillcfc73cc2019-04-08 16:26:51 -04006295 Texture *texture = context->getTextureByType(target);
Jamie Madillbe849e42017-05-02 15:49:00 -04006296
6297 if (texture == nullptr)
6298 {
Jamie Madille0472f32018-11-27 16:32:45 -05006299 context->validationError(GL_INVALID_OPERATION, kTextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006300 return false;
6301 }
6302
6303 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6304
6305 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6306 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6307 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6308 {
Jamie Madille0472f32018-11-27 16:32:45 -05006309 context->validationError(GL_INVALID_OPERATION, kBaseLevelOutOfRange);
Jamie Madillbe849e42017-05-02 15:49:00 -04006310 return false;
6311 }
6312
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006313 TextureTarget baseTarget = (target == TextureType::CubeMap)
6314 ? TextureTarget::CubeMapPositiveX
6315 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006316 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6317 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6318 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006319 {
Jamie Madille0472f32018-11-27 16:32:45 -05006320 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Brandon Jones6cad5662017-06-14 13:25:13 -07006321 return false;
6322 }
6323
Geoff Lang536eca12017-09-13 11:23:35 -04006324 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6325 bool formatUnsized = !format.sized;
6326 bool formatColorRenderableAndFilterable =
6327 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006328 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006329 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006330 {
Jamie Madille0472f32018-11-27 16:32:45 -05006331 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006332 return false;
6333 }
6334
Geoff Lang536eca12017-09-13 11:23:35 -04006335 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6336 // generation
6337 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6338 {
Jamie Madille0472f32018-11-27 16:32:45 -05006339 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Geoff Lang536eca12017-09-13 11:23:35 -04006340 return false;
6341 }
6342
Jiange2c00842018-07-13 16:50:49 +08006343 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6344 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6345 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006346 {
Jamie Madille0472f32018-11-27 16:32:45 -05006347 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006348 return false;
6349 }
6350
6351 // Non-power of 2 ES2 check
6352 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6353 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6354 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6355 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006356 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6357 target == TextureType::CubeMap);
Jamie Madille0472f32018-11-27 16:32:45 -05006358 context->validationError(GL_INVALID_OPERATION, kTextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006359 return false;
6360 }
6361
6362 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006363 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006364 {
Jamie Madille0472f32018-11-27 16:32:45 -05006365 context->validationError(GL_INVALID_OPERATION, kCubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006366 return false;
6367 }
6368
James Darpinian83b2f0e2018-11-27 15:56:01 -08006369 if (context->getExtensions().webglCompatibility &&
6370 (texture->getWidth(baseTarget, effectiveBaseLevel) == 0 ||
6371 texture->getHeight(baseTarget, effectiveBaseLevel) == 0))
6372 {
6373 context->validationError(GL_INVALID_OPERATION, kGenerateMipmapZeroSize);
6374 return false;
6375 }
6376
Jamie Madillbe849e42017-05-02 15:49:00 -04006377 return true;
6378}
6379
Jamie Madill5b772312018-03-08 20:28:32 -05006380bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006381 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006382 GLenum pname,
6383 GLint *params)
6384{
6385 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6386}
6387
6388bool ValidateGetRenderbufferParameteriv(Context *context,
6389 GLenum target,
6390 GLenum pname,
6391 GLint *params)
6392{
6393 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6394}
6395
6396bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6397{
6398 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6399}
6400
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006401bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006402{
6403 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6404}
6405
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006406bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006407{
6408 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6409}
6410
Till Rathmannb8543632018-10-02 19:46:14 +02006411bool ValidateGetTexParameterIivOES(Context *context,
6412 TextureType target,
6413 GLenum pname,
6414 GLint *params)
6415{
6416 if (context->getClientMajorVersion() < 3)
6417 {
Jamie Madille0472f32018-11-27 16:32:45 -05006418 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006419 return false;
6420 }
6421 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6422}
6423
6424bool ValidateGetTexParameterIuivOES(Context *context,
6425 TextureType target,
6426 GLenum pname,
6427 GLuint *params)
6428{
6429 if (context->getClientMajorVersion() < 3)
6430 {
Jamie Madille0472f32018-11-27 16:32:45 -05006431 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006432 return false;
6433 }
6434 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6435}
6436
Jamie Madillbe849e42017-05-02 15:49:00 -04006437bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6438{
6439 return ValidateGetUniformBase(context, program, location);
6440}
6441
6442bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6443{
6444 return ValidateGetUniformBase(context, program, location);
6445}
6446
6447bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6448{
6449 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6450}
6451
6452bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6453{
6454 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6455}
6456
6457bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6458{
6459 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6460}
6461
6462bool ValidateIsEnabled(Context *context, GLenum cap)
6463{
6464 if (!ValidCap(context, cap, true))
6465 {
Jamie Madille0472f32018-11-27 16:32:45 -05006466 context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006467 return false;
6468 }
6469
6470 return true;
6471}
6472
6473bool ValidateLinkProgram(Context *context, GLuint program)
6474{
6475 if (context->hasActiveTransformFeedback(program))
6476 {
6477 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006478 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
Jamie Madillbe849e42017-05-02 15:49:00 -04006479 return false;
6480 }
6481
6482 Program *programObject = GetValidProgram(context, program);
6483 if (!programObject)
6484 {
6485 return false;
6486 }
6487
6488 return true;
6489}
6490
Jamie Madill4928b7c2017-06-20 12:57:39 -04006491bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006492 GLint x,
6493 GLint y,
6494 GLsizei width,
6495 GLsizei height,
6496 GLenum format,
6497 GLenum type,
6498 void *pixels)
6499{
6500 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6501 nullptr, pixels);
6502}
6503
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006504bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006505{
Till Rathmannb8543632018-10-02 19:46:14 +02006506 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006507}
6508
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006509bool ValidateTexParameterfv(Context *context,
6510 TextureType target,
6511 GLenum pname,
6512 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006513{
Till Rathmannb8543632018-10-02 19:46:14 +02006514 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006515}
6516
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006517bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006518{
Till Rathmannb8543632018-10-02 19:46:14 +02006519 return ValidateTexParameterBase(context, target, pname, -1, false, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006520}
6521
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006522bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006523{
Till Rathmannb8543632018-10-02 19:46:14 +02006524 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6525}
6526
6527bool ValidateTexParameterIivOES(Context *context,
6528 TextureType target,
6529 GLenum pname,
6530 const GLint *params)
6531{
6532 if (context->getClientMajorVersion() < 3)
6533 {
Jamie Madille0472f32018-11-27 16:32:45 -05006534 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006535 return false;
6536 }
6537 return ValidateTexParameterBase(context, target, pname, -1, true, params);
6538}
6539
6540bool ValidateTexParameterIuivOES(Context *context,
6541 TextureType target,
6542 GLenum pname,
6543 const GLuint *params)
6544{
6545 if (context->getClientMajorVersion() < 3)
6546 {
Jamie Madille0472f32018-11-27 16:32:45 -05006547 context->validationError(GL_INVALID_OPERATION, kES3Required);
Till Rathmannb8543632018-10-02 19:46:14 +02006548 return false;
6549 }
6550 return ValidateTexParameterBase(context, target, pname, -1, true, params);
Jamie Madillbe849e42017-05-02 15:49:00 -04006551}
6552
6553bool ValidateUseProgram(Context *context, GLuint program)
6554{
6555 if (program != 0)
6556 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006557 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006558 if (!programObject)
6559 {
6560 // ES 3.1.0 section 7.3 page 72
6561 if (context->getShader(program))
6562 {
Jamie Madille0472f32018-11-27 16:32:45 -05006563 context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006564 return false;
6565 }
6566 else
6567 {
Jamie Madille0472f32018-11-27 16:32:45 -05006568 context->validationError(GL_INVALID_VALUE, kInvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006569 return false;
6570 }
6571 }
6572 if (!programObject->isLinked())
6573 {
Jamie Madille0472f32018-11-27 16:32:45 -05006574 context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006575 return false;
6576 }
6577 }
Jamie Madillc3dc5d42018-12-30 12:12:04 -05006578 if (context->getState().isTransformFeedbackActiveUnpaused())
Jamie Madillbe849e42017-05-02 15:49:00 -04006579 {
6580 // ES 3.0.4 section 2.15 page 91
Jamie Madillc3e37312018-11-30 15:25:39 -05006581 context->validationError(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
Jamie Madillbe849e42017-05-02 15:49:00 -04006582 return false;
6583 }
6584
6585 return true;
6586}
6587
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006588bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6589{
6590 if (!context->getExtensions().fence)
6591 {
Jamie Madille0472f32018-11-27 16:32:45 -05006592 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006593 return false;
6594 }
6595
6596 if (n < 0)
6597 {
Jamie Madille0472f32018-11-27 16:32:45 -05006598 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006599 return false;
6600 }
6601
6602 return true;
6603}
6604
6605bool ValidateFinishFenceNV(Context *context, GLuint fence)
6606{
6607 if (!context->getExtensions().fence)
6608 {
Jamie Madille0472f32018-11-27 16:32:45 -05006609 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006610 return false;
6611 }
6612
6613 FenceNV *fenceObject = context->getFenceNV(fence);
6614
6615 if (fenceObject == nullptr)
6616 {
Jamie Madille0472f32018-11-27 16:32:45 -05006617 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006618 return false;
6619 }
6620
6621 if (!fenceObject->isSet())
6622 {
Jamie Madille0472f32018-11-27 16:32:45 -05006623 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006624 return false;
6625 }
6626
6627 return true;
6628}
6629
6630bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6631{
6632 if (!context->getExtensions().fence)
6633 {
Jamie Madille0472f32018-11-27 16:32:45 -05006634 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006635 return false;
6636 }
6637
6638 if (n < 0)
6639 {
Jamie Madille0472f32018-11-27 16:32:45 -05006640 context->validationError(GL_INVALID_VALUE, kNegativeCount);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006641 return false;
6642 }
6643
6644 return true;
6645}
6646
6647bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6648{
6649 if (!context->getExtensions().fence)
6650 {
Jamie Madille0472f32018-11-27 16:32:45 -05006651 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006652 return false;
6653 }
6654
6655 FenceNV *fenceObject = context->getFenceNV(fence);
6656
6657 if (fenceObject == nullptr)
6658 {
Jamie Madille0472f32018-11-27 16:32:45 -05006659 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006660 return false;
6661 }
6662
6663 if (!fenceObject->isSet())
6664 {
Jamie Madille0472f32018-11-27 16:32:45 -05006665 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006666 return false;
6667 }
6668
6669 switch (pname)
6670 {
6671 case GL_FENCE_STATUS_NV:
6672 case GL_FENCE_CONDITION_NV:
6673 break;
6674
6675 default:
Jamie Madille0472f32018-11-27 16:32:45 -05006676 context->validationError(GL_INVALID_ENUM, kInvalidPname);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006677 return false;
6678 }
6679
6680 return true;
6681}
6682
6683bool ValidateGetGraphicsResetStatusEXT(Context *context)
6684{
6685 if (!context->getExtensions().robustness)
6686 {
Jamie Madille0472f32018-11-27 16:32:45 -05006687 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006688 return false;
6689 }
6690
6691 return true;
6692}
6693
6694bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6695 GLuint shader,
6696 GLsizei bufsize,
6697 GLsizei *length,
6698 GLchar *source)
6699{
6700 if (!context->getExtensions().translatedShaderSource)
6701 {
Jamie Madille0472f32018-11-27 16:32:45 -05006702 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006703 return false;
6704 }
6705
6706 if (bufsize < 0)
6707 {
Jamie Madille0472f32018-11-27 16:32:45 -05006708 context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006709 return false;
6710 }
6711
6712 Shader *shaderObject = context->getShader(shader);
6713
6714 if (!shaderObject)
6715 {
Jamie Madille0472f32018-11-27 16:32:45 -05006716 context->validationError(GL_INVALID_OPERATION, kInvalidShaderName);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006717 return false;
6718 }
6719
6720 return true;
6721}
6722
6723bool ValidateIsFenceNV(Context *context, GLuint fence)
6724{
6725 if (!context->getExtensions().fence)
6726 {
Jamie Madille0472f32018-11-27 16:32:45 -05006727 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006728 return false;
6729 }
6730
6731 return true;
6732}
6733
Jamie Madill007530e2017-12-28 14:27:04 -05006734bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6735{
6736 if (!context->getExtensions().fence)
6737 {
Jamie Madille0472f32018-11-27 16:32:45 -05006738 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006739 return false;
6740 }
6741
6742 if (condition != GL_ALL_COMPLETED_NV)
6743 {
Jamie Madille0472f32018-11-27 16:32:45 -05006744 context->validationError(GL_INVALID_ENUM, kInvalidFenceCondition);
Jamie Madill007530e2017-12-28 14:27:04 -05006745 return false;
6746 }
6747
6748 FenceNV *fenceObject = context->getFenceNV(fence);
6749
6750 if (fenceObject == nullptr)
6751 {
Jamie Madille0472f32018-11-27 16:32:45 -05006752 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006753 return false;
6754 }
6755
6756 return true;
6757}
6758
6759bool ValidateTestFenceNV(Context *context, GLuint fence)
6760{
6761 if (!context->getExtensions().fence)
6762 {
Jamie Madille0472f32018-11-27 16:32:45 -05006763 context->validationError(GL_INVALID_OPERATION, kNVFenceNotSupported);
Jamie Madill007530e2017-12-28 14:27:04 -05006764 return false;
6765 }
6766
6767 FenceNV *fenceObject = context->getFenceNV(fence);
6768
6769 if (fenceObject == nullptr)
6770 {
Jamie Madille0472f32018-11-27 16:32:45 -05006771 context->validationError(GL_INVALID_OPERATION, kInvalidFence);
Jamie Madill007530e2017-12-28 14:27:04 -05006772 return false;
6773 }
6774
6775 if (fenceObject->isSet() != GL_TRUE)
6776 {
Jamie Madille0472f32018-11-27 16:32:45 -05006777 context->validationError(GL_INVALID_OPERATION, kInvalidFenceState);
Jamie Madill007530e2017-12-28 14:27:04 -05006778 return false;
6779 }
6780
6781 return true;
6782}
6783
6784bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006785 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006786 GLsizei levels,
6787 GLenum internalformat,
6788 GLsizei width,
6789 GLsizei height)
6790{
6791 if (!context->getExtensions().textureStorage)
6792 {
Jamie Madille0472f32018-11-27 16:32:45 -05006793 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006794 return false;
6795 }
6796
6797 if (context->getClientMajorVersion() < 3)
6798 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006799 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006800 height);
6801 }
6802
6803 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006804 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006805 1);
6806}
6807
6808bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6809{
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006810 if (!context->getExtensions().instancedArraysANGLE)
Jamie Madill007530e2017-12-28 14:27:04 -05006811 {
Jamie Madille0472f32018-11-27 16:32:45 -05006812 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006813 return false;
6814 }
6815
6816 if (index >= MAX_VERTEX_ATTRIBS)
6817 {
Jamie Madille0472f32018-11-27 16:32:45 -05006818 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
Jamie Madill007530e2017-12-28 14:27:04 -05006819 return false;
6820 }
6821
6822 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6823 {
6824 if (index == 0 && divisor != 0)
6825 {
Jamie Madillc3e37312018-11-30 15:25:39 -05006826 context->validationError(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
Jamie Madill007530e2017-12-28 14:27:04 -05006827
6828 // We also output an error message to the debugger window if tracing is active, so
6829 // that developers can see the error message.
Jamie Madillc3e37312018-11-30 15:25:39 -05006830 ERR() << kAttributeZeroRequiresDivisorLimitation;
Jamie Madill007530e2017-12-28 14:27:04 -05006831 return false;
6832 }
6833 }
6834
6835 return true;
6836}
6837
Jonah Ryan-Davis2b0553c2019-02-08 10:07:21 -05006838bool ValidateVertexAttribDivisorEXT(Context *context, GLuint index, GLuint divisor)
6839{
6840 if (!context->getExtensions().instancedArraysEXT)
6841 {
6842 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6843 return false;
6844 }
6845
6846 if (index >= MAX_VERTEX_ATTRIBS)
6847 {
6848 context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6849 return false;
6850 }
6851
6852 return true;
6853}
6854
Jamie Madill007530e2017-12-28 14:27:04 -05006855bool ValidateTexImage3DOES(Context *context,
6856 GLenum target,
6857 GLint level,
6858 GLenum internalformat,
6859 GLsizei width,
6860 GLsizei height,
6861 GLsizei depth,
6862 GLint border,
6863 GLenum format,
6864 GLenum type,
6865 const void *pixels)
6866{
6867 UNIMPLEMENTED(); // FIXME
6868 return false;
6869}
6870
6871bool ValidatePopGroupMarkerEXT(Context *context)
6872{
6873 if (!context->getExtensions().debugMarker)
6874 {
6875 // The debug marker calls should not set error state
6876 // However, it seems reasonable to set an error state if the extension is not enabled
Jamie Madille0472f32018-11-27 16:32:45 -05006877 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madill007530e2017-12-28 14:27:04 -05006878 return false;
6879 }
6880
6881 return true;
6882}
6883
Jamie Madillfa920eb2018-01-04 11:45:50 -05006884bool ValidateTexStorage1DEXT(Context *context,
6885 GLenum target,
6886 GLsizei levels,
6887 GLenum internalformat,
6888 GLsizei width)
6889{
6890 UNIMPLEMENTED();
Jamie Madille0472f32018-11-27 16:32:45 -05006891 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006892 return false;
6893}
6894
6895bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006896 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006897 GLsizei levels,
6898 GLenum internalformat,
6899 GLsizei width,
6900 GLsizei height,
6901 GLsizei depth)
6902{
6903 if (!context->getExtensions().textureStorage)
6904 {
Jamie Madille0472f32018-11-27 16:32:45 -05006905 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006906 return false;
6907 }
6908
6909 if (context->getClientMajorVersion() < 3)
6910 {
Jamie Madille0472f32018-11-27 16:32:45 -05006911 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Jamie Madillfa920eb2018-01-04 11:45:50 -05006912 return false;
6913 }
6914
6915 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6916 depth);
6917}
6918
jchen1082af6202018-06-22 10:59:52 +08006919bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6920{
6921 if (!context->getExtensions().parallelShaderCompile)
6922 {
Jamie Madille0472f32018-11-27 16:32:45 -05006923 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
jchen1082af6202018-06-22 10:59:52 +08006924 return false;
6925 }
6926 return true;
6927}
6928
Austin Eng1bf18ce2018-10-19 15:34:02 -07006929bool ValidateMultiDrawArraysANGLE(Context *context,
6930 PrimitiveMode mode,
6931 const GLint *firsts,
6932 const GLsizei *counts,
6933 GLsizei drawcount)
6934{
6935 if (!context->getExtensions().multiDraw)
6936 {
Jamie Madille0472f32018-11-27 16:32:45 -05006937 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006938 return false;
6939 }
6940 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6941 {
6942 if (!ValidateDrawArrays(context, mode, firsts[drawID], counts[drawID]))
6943 {
6944 return false;
6945 }
6946 }
6947 return true;
6948}
6949
6950bool ValidateMultiDrawElementsANGLE(Context *context,
6951 PrimitiveMode mode,
6952 const GLsizei *counts,
Jamie Madill8dc27f92018-11-29 11:45:44 -05006953 DrawElementsType type,
Austin Eng3b7c9d02018-11-21 18:09:05 -08006954 const GLvoid *const *indices,
Austin Eng1bf18ce2018-10-19 15:34:02 -07006955 GLsizei drawcount)
6956{
6957 if (!context->getExtensions().multiDraw)
6958 {
Jamie Madille0472f32018-11-27 16:32:45 -05006959 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
Austin Eng1bf18ce2018-10-19 15:34:02 -07006960 return false;
6961 }
6962 for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6963 {
Austin Eng3b7c9d02018-11-21 18:09:05 -08006964 if (!ValidateDrawElements(context, mode, counts[drawID], type, indices[drawID]))
Austin Eng1bf18ce2018-10-19 15:34:02 -07006965 {
6966 return false;
6967 }
6968 }
6969 return true;
6970}
6971
Jeff Gilbert465d6092019-01-02 16:21:18 -08006972bool ValidateProvokingVertexANGLE(Context *context, ProvokingVertex modePacked)
6973{
6974 if (!context->getExtensions().provokingVertex)
6975 {
6976 context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
6977 return false;
6978 }
6979
6980 switch (modePacked)
6981 {
6982 case ProvokingVertex::FirstVertexConvention:
6983 case ProvokingVertex::LastVertexConvention:
6984 break;
6985 default:
6986 context->validationError(GL_INVALID_ENUM, kInvalidProvokingVertex);
6987 return false;
6988 }
6989
6990 return true;
6991}
6992
Jamie Madilla5410482019-01-31 19:55:55 -05006993void RecordBindTextureTypeError(Context *context, TextureType target)
6994{
6995 ASSERT(!context->getStateCache().isValidBindTextureType(target));
6996
6997 switch (target)
6998 {
6999 case TextureType::Rectangle:
7000 ASSERT(!context->getExtensions().textureRectangle);
7001 context->validationError(GL_INVALID_ENUM, kTextureRectangleNotSupported);
7002 break;
7003
7004 case TextureType::_3D:
7005 case TextureType::_2DArray:
7006 ASSERT(context->getClientMajorVersion() < 3);
7007 context->validationError(GL_INVALID_ENUM, kES3Required);
7008 break;
7009
7010 case TextureType::_2DMultisample:
7011 ASSERT(context->getClientVersion() < Version(3, 1) &&
7012 !context->getExtensions().textureMultisample);
7013 context->validationError(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
7014 break;
7015
7016 case TextureType::_2DMultisampleArray:
7017 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
7018 context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
7019 break;
7020
7021 case TextureType::External:
7022 ASSERT(!context->getExtensions().eglImageExternal &&
7023 !context->getExtensions().eglStreamConsumerExternal);
7024 context->validationError(GL_INVALID_ENUM, kExternalTextureNotSupported);
7025 break;
7026
7027 default:
7028 context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
7029 }
7030}
7031
Jamie Madillc29968b2016-01-20 11:17:23 -05007032} // namespace gl